<commit_before>#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

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

     char s1[]= "Hello, Mel. Today is sunday. Let's go party!";
fprintf (stdout,"%s -> %d\n",s1,strlen(s1) );

	return 0;
}

=============================================================

#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

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

     char s1[]= "Hello, Mel. Today is sunday. Let's go party!";

	strcat(s1, "Melaniya!");
fprintf (stdout,"%s -> %d\n",s1,strlen(s1) );
	return 0;
}

===============================================
Подава брой символи "strlen" :
fprintf (stdout,"strlen -> %s -> %d\n",s1,strlen(s1) );

===============================================

Добавя "strcat":
strcat(s1, "- From team! :)");

================================================

Сравнява "strcmp":
strcmp("Hello", "Hello") = 0
strcmp(s1, "Hello") = 1
strcmp("Hello", s1) = -1

================================================
Търси съвпадение на символ в стринга "*strchr" и дава съдържание:
fprintf (stdout,"strchr -> %c\n",*strchr("Hello", 'H'));

ако не ползване * се получава НОТА :) превърта;
#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

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

    char s1[]= "Hello, Mel. Today is sunday. Let's go party!";

  	strcat(s1, "- From team! :)");

fprintf (stdout,"strcmp -> %d\n",strcmp("Hello", "Hello"));

fprintf (stdout,"strchr -> %c\n",strchr("Hello", 'H'));

fprintf (stdout,"strlen -> %s -> %d\n",s1,strlen(s1) );
	return 0;
}
================================================
адрес за обръщане на масив в обратен ред

http://www.introprogramming.info/intro-csharp-book/read-online/glava7-masivi/

================================================

#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)

{

    char s1[]= "Hello, Mel. Today is sunday. Let's go party!";
    int i;

fprintf (stdout,"%s -> %d\n",s1,strlen(s1) );

for (i=0; i<strlen(s1);i++)

fprintf (stdout,"[%c]",s1[i]);

	return 0;
}

=============================================

#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)

{

    char s1[]= "Hello, Mel. Today is sunday. Let's go party!";
    int i;

fprintf (stdout,"%s -> %d\n",s1,strlen(s1) );

for (i=strlen(s1)-1;i>=0;i--)

fprintf (stdout,"%c",s1[i]);

	return 0;
}

=====================================
Функция за въвеждане на стойности за масив

float arr_f [50];
for (i=0;i<10;i++) {
     fprintf(stdout,"Enter a numer :");
     fscan (stdin,"%f", &arr_f[i]);
}
=====================================

#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main()

{

float arr_f[5], max;
int i;

for(i=0; i<4; i++)
 {
 	fprintf(stdout,"Enter a Number:");
 	fscanf(stdin,"%f",&arr_f[i]);
}
max = arr_f[i];
for(i=0; i<4; i++)
 {
 	if (max<arr_f[i])
	 fprintf(stdout,"MAX=%f",max);
}
return 0;
}
не изкарва резултат само вкарваш данни
===================================
<commit_msg>Update exercises_22.11.2014.cpp<commit_after>#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

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

     char s1[]= "Hello, Mel. Today is sunday. Let's go party!";
fprintf (stdout,"%s -> %d\n",s1,strlen(s1) );

	return 0;
}

=============================================================

#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

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

     char s1[]= "Hello, Mel. Today is sunday. Let's go party!";

	strcat(s1, "Melaniya!");
fprintf (stdout,"%s -> %d\n",s1,strlen(s1) );
	return 0;
}

===============================================
Подава брой символи "strlen" :
fprintf (stdout,"strlen -> %s -> %d\n",s1,strlen(s1) );

===============================================

Добавя "strcat":
strcat(s1, "- From team! :)");

================================================

Сравнява "strcmp":
strcmp("Hello", "Hello") = 0
strcmp(s1, "Hello") = 1
strcmp("Hello", s1) = -1

================================================
Търси съвпадение на символ в стринга "*strchr" и дава съдържание:
fprintf (stdout,"strchr -> %c\n",*strchr("Hello", 'H'));

ако не ползване * се получава НОТА :) превърта;
#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

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

    char s1[]= "Hello, Mel. Today is sunday. Let's go party!";

  	strcat(s1, "- From team! :)");

fprintf (stdout,"strcmp -> %d\n",strcmp("Hello", "Hello"));

fprintf (stdout,"strchr -> %c\n",strchr("Hello", 'H'));

fprintf (stdout,"strlen -> %s -> %d\n",s1,strlen(s1) );
	return 0;
}
================================================
адрес за обръщане на масив в обратен ред

http://www.introprogramming.info/intro-csharp-book/read-online/glava7-masivi/

================================================

#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)

{

    char s1[]= "Hello, Mel. Today is sunday. Let's go party!";
    int i;

fprintf (stdout,"%s -> %d\n",s1,strlen(s1) );

for (i=0; i<strlen(s1);i++)

fprintf (stdout,"[%c]",s1[i]);

	return 0;
}

=============================================

#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)

{

    char s1[]= "Hello, Mel. Today is sunday. Let's go party!";
    int i;

fprintf (stdout,"%s -> %d\n",s1,strlen(s1) );

for (i=strlen(s1)-1;i>=0;i--)

fprintf (stdout,"%c",s1[i]);

	return 0;
}

=====================================
Функция за въвеждане на стойности за масив

float arr_f [50];
for (i=0;i<10;i++) {
     fprintf(stdout,"Enter a numer :");
     fscan (stdin,"%f", &arr_f[i]);
}
=====================================

#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main()

{

float arr_f[5], max;
int i;

for(i=0; i<4; i++)
 {
 	fprintf(stdout,"Enter a Number:");
 	fscanf(stdin,"%f",&arr_f[i]);
}

max = arr_f[0];

for(i=0; i<4; i++)
 {
 	if (max<arr_f[i]) max =arr_f[i];

}
fprintf(stdout,"MAX=%f",max);
return 0;
}

дава резултат
============================================

<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling | FileCheck %s

// Checks for infinite recursion when we combine nested calls of process line
// with global initializers.

#include "cling/Interpreter/Interpreter.h"

class MyClass { public:  MyClass(){ gCling->process("gCling->getVersion()");} };

MyClass *My = new MyClass(); // CHECK: (const char *) "{{.*}}"

extern "C" int printf(const char*...);

struct S {
  S() {
    printf("Exec\n");
    gCling->process("printf(\"RecursiveExec\\n\");");
  }
} s;
// CHECK-NEXT:Exec
// CHECK-NEXT:RecursiveExec
gCling->process("int RecursiveInit = printf(\"A\\n\");");
int ForceInitSequence = 17;

// CHECK-NEXT:A

// CHECK-EMPTY:

.q
<commit_msg>Add forgotten comment as part of d7da914fa0<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling | FileCheck %s

// Checks for infinite recursion when we combine nested calls of process line
// with global initializers.

#include "cling/Interpreter/Interpreter.h"

class MyClass { public:  MyClass(){ gCling->process("gCling->getVersion()");} };

MyClass *My = new MyClass(); // CHECK: (const char *) "{{.*}}"

extern "C" int printf(const char*...);

// from https://sft.its.cern.ch/jira/browse/ROOT-5856?focusedCommentId=30869&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-30869
struct S {
  S() {
    printf("Exec\n");
    gCling->process("printf(\"RecursiveExec\\n\");");
  }
} s;
// CHECK-NEXT:Exec
// CHECK-NEXT:RecursiveExec
gCling->process("int RecursiveInit = printf(\"A\\n\");");
int ForceInitSequence = 17;

// CHECK-NEXT:A

// CHECK-EMPTY:

.q
<|endoftext|>


<commit_before>/*
 * The StockMap class is a hash table of any number of Stock objects,
 * each with a different URI.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "hstock.hxx"
#include "stock.hxx"
#include "pool.hxx"
#include "util/djbhash.h"

#include <daemon/log.h>

#include <assert.h>

#include <boost/intrusive/unordered_set.hpp>

struct StockMap {
    struct Item
        : boost::intrusive::unordered_set_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
        const char *const uri;

        Stock &stock;

        Item(const char *_uri, Stock &_stock):uri(_uri), stock(_stock) {}

        Item(const Item &) = delete;

        ~Item() {
            stock_free(&stock);
        }

        gcc_pure
        static size_t KeyHasher(const char *key) {
            assert(key != nullptr);

            return djb_hash_string(key);
        }

        gcc_pure
        static size_t ValueHasher(const Item &value) {
            return KeyHasher(value.uri);
        }

        gcc_pure
        static bool KeyValueEqual(const char *a, const Item &b) {
            assert(a != nullptr);

            return strcmp(a, b.uri) == 0;
        }

        struct Hash {
            gcc_pure
            size_t operator()(const Item &value) const {
                return ValueHasher(value);
            }
        };

        struct Equal {
            gcc_pure
            bool operator()(const Item &a, const Item &b) const {
                return KeyValueEqual(a.uri, b);
            }
        };

        struct Disposer {
            void operator()(Item *item) const {
                delete item;
            }
        };
    };

    typedef boost::intrusive::unordered_set<Item,
                                            boost::intrusive::hash<Item::Hash>,
                                            boost::intrusive::equal<Item::Equal>,
                                            boost::intrusive::constant_time_size<false>> Map;

    struct pool &pool;
    const StockClass &cls;
    void *const class_ctx;

    /**
     * The maximum number of items in each stock.
     */
    const unsigned limit;

    /**
     * The maximum number of permanent idle items in each stock.
     */
    const unsigned max_idle;

    Map map;

    static constexpr size_t N_BUCKETS = 251;
    Map::bucket_type buckets[N_BUCKETS];

    StockMap(struct pool &_pool, const StockClass &_cls, void *_class_ctx,
             unsigned _limit, unsigned _max_idle)
        :pool(*pool_new_libc(&_pool, "hstock")),
         cls(_cls), class_ctx(_class_ctx),
         limit(_limit), max_idle(_max_idle),
         map(Map::bucket_traits(buckets, N_BUCKETS)) {}

    ~StockMap() {
        map.clear_and_dispose(Item::Disposer());
    }

    void Destroy() {
        DeleteUnrefPool(pool, this);
    }

    void Erase(gcc_unused Stock &stock, const char *uri) {
#ifndef NDEBUG
        auto i = map.find(uri, Item::KeyHasher, Item::KeyValueEqual);
        assert(i != map.end());
        assert(&i->stock == &stock);
#endif

        map.erase_and_dispose(uri, Item::KeyHasher, Item::KeyValueEqual,
                              Item::Disposer());
    }

    void FadeAll() {
        for (auto &i : map)
            stock_fade_all(i.stock);
    }

    void AddStats(StockStats &data) const {
        for (const auto &i : map)
            stock_add_stats(i.stock, data);
    }

    Stock &GetStock(const char *uri);

    void Get(struct pool &caller_pool,
             const char *uri, void *info,
             const StockGetHandler &handler, void *handler_ctx,
             struct async_operation_ref &async_ref) {
        Stock &stock = GetStock(uri);
        stock_get(stock, caller_pool, info, handler, handler_ctx, async_ref);
    }

    StockItem *GetNow(struct pool &caller_pool, const char *uri, void *info,
                      GError **error_r) {
        Stock &stock = GetStock(uri);
        return stock_get_now(stock, caller_pool, info, error_r);
    }

    void Put(gcc_unused const char *uri, StockItem &object, bool destroy) {
#ifndef NDEBUG
        auto i = map.find(uri, Item::KeyHasher, Item::KeyValueEqual);
        assert(i != map.end());
        assert(&i->stock == object.stock);
#endif

        stock_put(object, destroy);
    }
};

/*
 * stock handler
 *
 */

static void
hstock_stock_empty(Stock &stock, const char *uri, void *ctx)
{
    StockMap *hstock = (StockMap *)ctx;

    daemon_log(5, "hstock(%p) remove empty stock(%p, '%s')\n",
               (const void *)hstock, (const void *)&stock, uri);

    hstock->Erase(stock, uri);
}

static constexpr StockHandler hstock_stock_handler = {
    .empty = hstock_stock_empty,
};

StockMap *
hstock_new(struct pool &pool, const StockClass &cls, void *class_ctx,
           unsigned limit, unsigned max_idle)
{
    assert(cls.item_size > sizeof(StockItem));
    assert(cls.create != nullptr);
    assert(cls.borrow != nullptr);
    assert(cls.release != nullptr);
    assert(cls.destroy != nullptr);
    assert(max_idle > 0);

    return NewFromPool<StockMap>(pool, pool, cls, class_ctx,
                                 limit, max_idle);
}

void
hstock_free(StockMap *hstock)
{
    hstock->Destroy();
}

void
hstock_fade_all(StockMap &hstock)
{
    hstock.FadeAll();
}

void
hstock_add_stats(const StockMap &stock, StockStats &data)
{
    stock.AddStats(data);
}

inline Stock &
StockMap::GetStock(const char *uri)
{
    Map::insert_commit_data hint;
    auto i = map.insert_check(uri, Item::KeyHasher, Item::KeyValueEqual, hint);
    if (i.second) {
        auto *stock = stock_new(pool, cls, class_ctx,
                                uri, limit, max_idle,
                                hstock_stock_handler, this);
        map.insert_commit(*new Item(stock_get_uri(*stock), *stock), hint);
        return *stock;
    } else
        return i.first->stock;

}

void
hstock_get(StockMap &hstock, struct pool &pool,
           const char *uri, void *info,
           const StockGetHandler &handler, void *handler_ctx,
           struct async_operation_ref &async_ref)
{
    return hstock.Get(pool, uri, info,
                      handler, handler_ctx, async_ref);
}

StockItem *
hstock_get_now(StockMap &hstock, struct pool &pool,
               const char *uri, void *info,
               GError **error_r)
{
    return hstock.GetNow(pool, uri, info, error_r);
}

void
hstock_put(StockMap &hstock, const char *uri, StockItem &object, bool destroy)
{
    hstock.Put(uri, object, destroy);
}
<commit_msg>hstock: add missing include<commit_after>/*
 * The StockMap class is a hash table of any number of Stock objects,
 * each with a different URI.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "hstock.hxx"
#include "stock.hxx"
#include "pool.hxx"
#include "util/djbhash.h"

#include <daemon/log.h>

#include <assert.h>
#include <string.h>

#include <boost/intrusive/unordered_set.hpp>

struct StockMap {
    struct Item
        : boost::intrusive::unordered_set_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
        const char *const uri;

        Stock &stock;

        Item(const char *_uri, Stock &_stock):uri(_uri), stock(_stock) {}

        Item(const Item &) = delete;

        ~Item() {
            stock_free(&stock);
        }

        gcc_pure
        static size_t KeyHasher(const char *key) {
            assert(key != nullptr);

            return djb_hash_string(key);
        }

        gcc_pure
        static size_t ValueHasher(const Item &value) {
            return KeyHasher(value.uri);
        }

        gcc_pure
        static bool KeyValueEqual(const char *a, const Item &b) {
            assert(a != nullptr);

            return strcmp(a, b.uri) == 0;
        }

        struct Hash {
            gcc_pure
            size_t operator()(const Item &value) const {
                return ValueHasher(value);
            }
        };

        struct Equal {
            gcc_pure
            bool operator()(const Item &a, const Item &b) const {
                return KeyValueEqual(a.uri, b);
            }
        };

        struct Disposer {
            void operator()(Item *item) const {
                delete item;
            }
        };
    };

    typedef boost::intrusive::unordered_set<Item,
                                            boost::intrusive::hash<Item::Hash>,
                                            boost::intrusive::equal<Item::Equal>,
                                            boost::intrusive::constant_time_size<false>> Map;

    struct pool &pool;
    const StockClass &cls;
    void *const class_ctx;

    /**
     * The maximum number of items in each stock.
     */
    const unsigned limit;

    /**
     * The maximum number of permanent idle items in each stock.
     */
    const unsigned max_idle;

    Map map;

    static constexpr size_t N_BUCKETS = 251;
    Map::bucket_type buckets[N_BUCKETS];

    StockMap(struct pool &_pool, const StockClass &_cls, void *_class_ctx,
             unsigned _limit, unsigned _max_idle)
        :pool(*pool_new_libc(&_pool, "hstock")),
         cls(_cls), class_ctx(_class_ctx),
         limit(_limit), max_idle(_max_idle),
         map(Map::bucket_traits(buckets, N_BUCKETS)) {}

    ~StockMap() {
        map.clear_and_dispose(Item::Disposer());
    }

    void Destroy() {
        DeleteUnrefPool(pool, this);
    }

    void Erase(gcc_unused Stock &stock, const char *uri) {
#ifndef NDEBUG
        auto i = map.find(uri, Item::KeyHasher, Item::KeyValueEqual);
        assert(i != map.end());
        assert(&i->stock == &stock);
#endif

        map.erase_and_dispose(uri, Item::KeyHasher, Item::KeyValueEqual,
                              Item::Disposer());
    }

    void FadeAll() {
        for (auto &i : map)
            stock_fade_all(i.stock);
    }

    void AddStats(StockStats &data) const {
        for (const auto &i : map)
            stock_add_stats(i.stock, data);
    }

    Stock &GetStock(const char *uri);

    void Get(struct pool &caller_pool,
             const char *uri, void *info,
             const StockGetHandler &handler, void *handler_ctx,
             struct async_operation_ref &async_ref) {
        Stock &stock = GetStock(uri);
        stock_get(stock, caller_pool, info, handler, handler_ctx, async_ref);
    }

    StockItem *GetNow(struct pool &caller_pool, const char *uri, void *info,
                      GError **error_r) {
        Stock &stock = GetStock(uri);
        return stock_get_now(stock, caller_pool, info, error_r);
    }

    void Put(gcc_unused const char *uri, StockItem &object, bool destroy) {
#ifndef NDEBUG
        auto i = map.find(uri, Item::KeyHasher, Item::KeyValueEqual);
        assert(i != map.end());
        assert(&i->stock == object.stock);
#endif

        stock_put(object, destroy);
    }
};

/*
 * stock handler
 *
 */

static void
hstock_stock_empty(Stock &stock, const char *uri, void *ctx)
{
    StockMap *hstock = (StockMap *)ctx;

    daemon_log(5, "hstock(%p) remove empty stock(%p, '%s')\n",
               (const void *)hstock, (const void *)&stock, uri);

    hstock->Erase(stock, uri);
}

static constexpr StockHandler hstock_stock_handler = {
    .empty = hstock_stock_empty,
};

StockMap *
hstock_new(struct pool &pool, const StockClass &cls, void *class_ctx,
           unsigned limit, unsigned max_idle)
{
    assert(cls.item_size > sizeof(StockItem));
    assert(cls.create != nullptr);
    assert(cls.borrow != nullptr);
    assert(cls.release != nullptr);
    assert(cls.destroy != nullptr);
    assert(max_idle > 0);

    return NewFromPool<StockMap>(pool, pool, cls, class_ctx,
                                 limit, max_idle);
}

void
hstock_free(StockMap *hstock)
{
    hstock->Destroy();
}

void
hstock_fade_all(StockMap &hstock)
{
    hstock.FadeAll();
}

void
hstock_add_stats(const StockMap &stock, StockStats &data)
{
    stock.AddStats(data);
}

inline Stock &
StockMap::GetStock(const char *uri)
{
    Map::insert_commit_data hint;
    auto i = map.insert_check(uri, Item::KeyHasher, Item::KeyValueEqual, hint);
    if (i.second) {
        auto *stock = stock_new(pool, cls, class_ctx,
                                uri, limit, max_idle,
                                hstock_stock_handler, this);
        map.insert_commit(*new Item(stock_get_uri(*stock), *stock), hint);
        return *stock;
    } else
        return i.first->stock;

}

void
hstock_get(StockMap &hstock, struct pool &pool,
           const char *uri, void *info,
           const StockGetHandler &handler, void *handler_ctx,
           struct async_operation_ref &async_ref)
{
    return hstock.Get(pool, uri, info,
                      handler, handler_ctx, async_ref);
}

StockItem *
hstock_get_now(StockMap &hstock, struct pool &pool,
               const char *uri, void *info,
               GError **error_r)
{
    return hstock.GetNow(pool, uri, info, error_r);
}

void
hstock_put(StockMap &hstock, const char *uri, StockItem &object, bool destroy)
{
    hstock.Put(uri, object, destroy);
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	スイッチ入力・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RL78/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>

namespace utils {

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  SW2 クラス
		@param[in]	B0	ビット０
		@param[in]	B1	ビット１
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class B0, class B1>
	class sw2 {
	public:

        //-----------------------------------------------------------------//
        /*!
            @brief  開始
        */
        //-----------------------------------------------------------------//
		void start() {
			B0::DIR = 0;
			B1::DIR = 0;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
			@return 値
        */
        //-----------------------------------------------------------------//
		uint8_t get() const {
			uint8_t l = static_cast<uint8_t>(B0::P()) | (static_cast<uint8_t>(B1::P()) << 1);
			return l ^ 0b11;
		}
	};

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  SW5 クラス
		@param[in]	B0	ビット０
		@param[in]	B1	ビット１
		@param[in]	B2	ビット２
		@param[in]	B3	ビット３
		@param[in]	B4	ビット４
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class B0, class B1, class B2, class B3, class B4>
	class sw5 {
	public:

        //-----------------------------------------------------------------//
        /*!
            @brief  開始
        */
        //-----------------------------------------------------------------//
		void start() {
			B0::DIR = 0;
			B1::DIR = 0;
			B2::DIR = 0;
			B3::DIR = 0;
			B4::DIR = 0;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
			@return 値
        */
        //-----------------------------------------------------------------//
		uint8_t get() const {
			uint8_t v = static_cast<uint8_t>(B0::P())
					 | (static_cast<uint8_t>(B1::P()) << 1)
					 | (static_cast<uint8_t>(B2::P()) << 2)
					 | (static_cast<uint8_t>(B3::P()) << 3)
					 | (static_cast<uint8_t>(B4::P()) << 4);
			return v ^ 0b11111;
		}
	};
}
<commit_msg>update positive/negative trigger<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	スイッチ入力・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RL78/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>

namespace utils {

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  SW2 クラス
		@param[in]	B0	ビット０
		@param[in]	B1	ビット１
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class B0, class B1>
	class sw2 {
		uint8_t		lvl_;
		uint8_t		neg_;
		uint8_t		pos_;

	public:
        //-----------------------------------------------------------------//
        /*!
            @brief  コンストラクタ
        */
        //-----------------------------------------------------------------//
		sw2() : lvl_(0), neg_(0), pos_(0) { }

        //-----------------------------------------------------------------//
        /*!
            @brief  レベルの取得
			@return レベル
        */
        //-----------------------------------------------------------------//
		uint8_t level() const { return lvl_; }

        //-----------------------------------------------------------------//
        /*!
            @brief  押した瞬間の取得
			@return 押した瞬間
        */
        //-----------------------------------------------------------------//
		uint8_t positive() const { return pos_; }

        //-----------------------------------------------------------------//
        /*!
            @brief  離した瞬間の取得
			@return 離した瞬間
        */
        //-----------------------------------------------------------------//
		uint8_t negative() const { return neg_; }

        //-----------------------------------------------------------------//
        /*!
            @brief  開始
        */
        //-----------------------------------------------------------------//
		void start() {
			B0::DIR = 0;
			B1::DIR = 0;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
			@return 値
        */
        //-----------------------------------------------------------------//
		uint8_t get() const {
			uint8_t l = static_cast<uint8_t>(B0::P()) | (static_cast<uint8_t>(B1::P()) << 1);
			return l ^ 0b11;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  サービス
        */
        //-----------------------------------------------------------------//
		void service()
		{
			uint8_t lvl = get();
			pos_ =  lvl & ~lvl_;
			neg_ = ~lvl &  lvl_;
			lvl_ = lvl;
		}

	};

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  SW5 クラス
		@param[in]	B0	ビット０
		@param[in]	B1	ビット１
		@param[in]	B2	ビット２
		@param[in]	B3	ビット３
		@param[in]	B4	ビット４
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class B0, class B1, class B2, class B3, class B4>
	class sw5 {
	public:

        //-----------------------------------------------------------------//
        /*!
            @brief  開始
        */
        //-----------------------------------------------------------------//
		void start() {
			B0::DIR = 0;
			B1::DIR = 0;
			B2::DIR = 0;
			B3::DIR = 0;
			B4::DIR = 0;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
			@return 値
        */
        //-----------------------------------------------------------------//
		uint8_t get() const {
			uint8_t v = static_cast<uint8_t>(B0::P())
					 | (static_cast<uint8_t>(B1::P()) << 1)
					 | (static_cast<uint8_t>(B2::P()) << 2)
					 | (static_cast<uint8_t>(B3::P()) << 3)
					 | (static_cast<uint8_t>(B4::P()) << 4);
			return v ^ 0b11111;
		}
	};
}
<|endoftext|>


<commit_before>#include "./camera.h"
#include <Eigen/Geometry>
#include <iostream>
#include <math.h>

Camera::Camera()
  : position(0, 0, 4), direction(0, 0, -1), up(0, 1, 0), radius(4.0f),
    azimuth(M_PI / 2.0f), declination(0)
{
  projection = createProjection(M_PI / 2.0f, 16.0f / 9.0f, 0.1f, 100.0f);
}

Camera::~Camera()
{
}

Eigen::Matrix4f Camera::createProjection(float fov, float aspectRatio,
                                         float nearPlane, float farPlane)
{
  double tanHalfFovy = tan(fov / 2.0);
  Eigen::Matrix4f result = Eigen::Matrix4f::Zero();
  result(0, 0) = 1.0 / (aspectRatio * tanHalfFovy);
  result(1, 1) = 1.0 / (tanHalfFovy);
  result(2, 2) = -(farPlane + nearPlane) / (farPlane - nearPlane);
  result(3, 2) = -1.0;
  result(2, 3) = -(2.0 * farPlane * nearPlane) / (farPlane - nearPlane);

  return result;
}

void Camera::moveForward(float distance)
{
  position += distance * direction;
}

void Camera::moveBackward(float distance)
{
  position -= distance * direction;
}

void Camera::strafeLeft(float distance)
{
  auto right = direction.cross(up);
  position -= distance * right;
}

void Camera::strafeRight(float distance)
{
  auto right = direction.cross(up);
  position += distance * right;
}

void Camera::changeAzimuth(float deltaAngle)
{
  azimuth += deltaAngle;
  update();
}

void Camera::changeDeclination(float deltaAngle)
{
  declination += deltaAngle;
  update();
}

void Camera::changeRadius(float deltaRadius)
{
  radius += deltaRadius;
  update();
}

void Camera::update()
{
  radius = position.norm();
  position = Eigen::Vector3f(cos(azimuth) * cos(declination), sin(declination),
                             sin(azimuth) * cos(declination)) *
             radius;
  direction = -position.normalized();
  float upDeclination = declination - M_PI / 2.0f;
  up = -Eigen::Vector3f(cos(azimuth) * cos(upDeclination), sin(upDeclination),
                        sin(azimuth) * cos(upDeclination)).normalized();
}

Eigen::Matrix4f Camera::getViewMatrix()
{
  std::cout << "pos: " << position << std::endl;
  auto n = direction.normalized();
  auto u = up.cross(n).normalized();
  auto v = n.cross(u);
  auto e = position;

  view << u.x(), u.y(), u.z(), u.dot(e),
       v.x(), v.y(), v.z(), v.dot(e),
       n.x(), n.y(), n.z(), n.dot(e),
       0, 0, 0, 1;

  std::cout << view << std::endl;

  return view;
}

Eigen::Matrix4f Camera::getProjectionMatrix()
{
  return projection;
}

<commit_msg>Remove debug output.<commit_after>#include "./camera.h"
#include <Eigen/Geometry>
#include <math.h>

Camera::Camera()
  : position(0, 0, 4), direction(0, 0, -1), up(0, 1, 0), radius(4.0f),
    azimuth(M_PI / 2.0f), declination(0)
{
  projection = createProjection(M_PI / 2.0f, 16.0f / 9.0f, 0.1f, 100.0f);
}

Camera::~Camera()
{
}

Eigen::Matrix4f Camera::createProjection(float fov, float aspectRatio,
                                         float nearPlane, float farPlane)
{
  double tanHalfFovy = tan(fov / 2.0);
  Eigen::Matrix4f result = Eigen::Matrix4f::Zero();
  result(0, 0) = 1.0 / (aspectRatio * tanHalfFovy);
  result(1, 1) = 1.0 / (tanHalfFovy);
  result(2, 2) = -(farPlane + nearPlane) / (farPlane - nearPlane);
  result(3, 2) = -1.0;
  result(2, 3) = -(2.0 * farPlane * nearPlane) / (farPlane - nearPlane);

  return result;
}

void Camera::moveForward(float distance)
{
  position += distance * direction;
}

void Camera::moveBackward(float distance)
{
  position -= distance * direction;
}

void Camera::strafeLeft(float distance)
{
  auto right = direction.cross(up);
  position -= distance * right;
}

void Camera::strafeRight(float distance)
{
  auto right = direction.cross(up);
  position += distance * right;
}

void Camera::changeAzimuth(float deltaAngle)
{
  azimuth += deltaAngle;
  update();
}

void Camera::changeDeclination(float deltaAngle)
{
  declination += deltaAngle;
  update();
}

void Camera::changeRadius(float deltaRadius)
{
  radius += deltaRadius;
  update();
}

void Camera::update()
{
  radius = position.norm();
  position = Eigen::Vector3f(cos(azimuth) * cos(declination), sin(declination),
                             sin(azimuth) * cos(declination)) *
             radius;
  direction = -position.normalized();
  float upDeclination = declination - M_PI / 2.0f;
  up = -Eigen::Vector3f(cos(azimuth) * cos(upDeclination), sin(upDeclination),
                        sin(azimuth) * cos(upDeclination)).normalized();
}

Eigen::Matrix4f Camera::getViewMatrix()
{
  auto n = direction.normalized();
  auto u = up.cross(n).normalized();
  auto v = n.cross(u);
  auto e = position;

  view << u.x(), u.y(), u.z(), u.dot(e),
       v.x(), v.y(), v.z(), v.dot(e),
       n.x(), n.y(), n.z(), n.dot(e),
       0, 0, 0, 1;

  return view;
}

Eigen::Matrix4f Camera::getProjectionMatrix()
{
  return projection;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009 by Marc Boris Duerner, Tommi Maekitalo
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "clientimpl.h"
#include <cxxtools/http/client.h>
#include "parser.h"
#include <cxxtools/ioerror.h>
#include <cxxtools/textstream.h>
#include <cxxtools/base64codec.h>
#include <sstream>

#include <cxxtools/log.h>

log_define("cxxtools.http.client.impl")

namespace cxxtools {

namespace http {

void ClientImpl::ParseEvent::onHttpReturn(unsigned ret, const std::string& text)
{
    _replyHeader.httpReturn(ret, text);
}

ClientImpl::ClientImpl(Client* client)
: _client(client)
, _parseEvent(_replyHeader)
, _parser(_parseEvent, true)
, _request(0)
, _stream(8192, true)
, _readHeader(true)
, _contentLength(0)
, _chunkedEncoding(false)
, _chunkedIStream(_stream.rdbuf())
{
    _stream.attachDevice(_socket);
    cxxtools::connect(_socket.connected, *this, &ClientImpl::onConnect);
    cxxtools::connect(_socket.errorOccured, *this, &ClientImpl::onErrorOccured);
    cxxtools::connect(_stream.buffer().outputReady, *this, &ClientImpl::onOutput);
    cxxtools::connect(_stream.buffer().inputReady, *this, &ClientImpl::onInput);
}

ClientImpl::ClientImpl(Client* client, const net::AddrInfo& addrinfo)
: _client(client)
, _parseEvent(_replyHeader)
, _parser(_parseEvent, true)
, _request(0)
, _addrInfo(addrinfo)
, _stream(8192, true)
, _readHeader(true)
, _contentLength(0)
, _chunkedEncoding(false)
, _chunkedIStream(_stream.rdbuf())
{
    _stream.attachDevice(_socket);
    cxxtools::connect(_socket.connected, *this, &ClientImpl::onConnect);
    cxxtools::connect(_socket.errorOccured, *this, &ClientImpl::onErrorOccured);
    cxxtools::connect(_stream.buffer().outputReady, *this, &ClientImpl::onOutput);
    cxxtools::connect(_stream.buffer().inputReady, *this, &ClientImpl::onInput);
}

ClientImpl::ClientImpl(Client* client, SelectorBase& selector, const net::AddrInfo& addrinfo)
: _client(client)
, _parseEvent(_replyHeader)
, _parser(_parseEvent, true)
, _request(0)
, _addrInfo(addrinfo)
, _stream(8192, true)
, _readHeader(true)
, _contentLength(0)
, _chunkedEncoding(false)
, _chunkedIStream(_stream.rdbuf())
{
    _stream.attachDevice(_socket);
    cxxtools::connect(_socket.connected, *this, &ClientImpl::onConnect);
    cxxtools::connect(_socket.errorOccured, *this, &ClientImpl::onErrorOccured);
    cxxtools::connect(_stream.buffer().outputReady, *this, &ClientImpl::onOutput);
    cxxtools::connect(_stream.buffer().inputReady, *this, &ClientImpl::onInput);
    setSelector(selector);
}

void ClientImpl::setSelector(SelectorBase& selector)
{
    selector.add(_socket);
}

void ClientImpl::reexecute(const Request& request)
{
    log_debug("reconnect");
    _socket.connect(_addrInfo);

    _stream.clear();
    _stream.buffer().discard();
    sendRequest(request);
    _stream.flush();
}

void ClientImpl::doparse()
{
    char ch;
    while (!_parser.end() && _stream.get(ch))
        _parser.parse(ch);

}

const ReplyHeader& ClientImpl::execute(const Request& request, std::size_t timeout)
{
    log_trace("execute request " << request.url());

    _replyHeader.clear();

    _socket.setTimeout(timeout);

    bool shouldReconnect = _socket.isConnected();
    if (!shouldReconnect)
    {
        log_debug("connect");
        _socket.connect(_addrInfo);
    }

    log_debug("send request");
    sendRequest(request);
    log_debug("flush stream");
    _stream.flush();

    log_debug("flush stream ready");
    if (!_stream && shouldReconnect)
    {
        // sending failed and we were not connected before, so try again
        reexecute(request);
        shouldReconnect = false;
    }

    if (!_stream)
        throw IOError( CXXTOOLS_ERROR_MSG("error sending HTTP request") );

    log_debug("read reply");

    _parser.reset(true);
    _readHeader = true;
    doparse();

    if (_parser.begin() && shouldReconnect)
    {
        // reading failed and we were not connected before, so try again
        reexecute(request);

        if (!_stream)
            throw IOError( CXXTOOLS_ERROR_MSG("error sending HTTP request") );

        doparse();
    }

    log_debug("reply ready");

    if (_stream.fail())
        throw IOError( CXXTOOLS_ERROR_MSG("failed to read HTTP reply") );

    if (_parser.fail())
        throw IOError( CXXTOOLS_ERROR_MSG("invalid HTTP reply") );

    if (!_parser.end())
        throw IOError( CXXTOOLS_ERROR_MSG("incomplete HTTP reply header") );

    return _replyHeader;
}

void ClientImpl::readBody(std::string& s)
{
    s.clear();

    _chunkedEncoding = _replyHeader.chunkedTransferEncoding();
    _chunkedIStream.reset();

    if (_chunkedEncoding)
    {
        log_debug("read body with chunked encoding");

        char ch;
        while (_chunkedIStream.get(ch))
            s += ch;

        log_debug("eod=" << _chunkedIStream.eod());

        if (_chunkedIStream.eod())
        {
            _parser.readHeader();
            doparse();

            if (_parser.fail())
                throw std::runtime_error("http parser failed"); // TODO define exception class
        }
        else
            throw std::runtime_error("chunked stream not complete");
    }
    else
    {
        unsigned n = _replyHeader.contentLength();

        log_debug("read body; content-size: " << n);

        s.reserve(n);

        char ch;
        while (n-- && _stream.get(ch))
            s += ch;

        if (_stream.fail())
            throw IOError( CXXTOOLS_ERROR_MSG("error reading HTTP reply body") );

        //log_debug("body read: \"" << s << '"');
    }

    if (!_replyHeader.keepAlive())
    {
        log_debug("close socket - no keep alive");
        _socket.close();
    }
    else
    {
        log_debug("do not close socket - keep alive");
    }
}

std::string ClientImpl::get(const std::string& url, std::size_t timeout)
{
    Request request(url);
    execute(request, timeout);
    return readBody();
}

void ClientImpl::beginExecute(const Request& request)
{
    _request = &request;
    _replyHeader.clear();
    if (_socket.isConnected())
    {
        sendRequest(*_request);
        try
        {
            _stream.buffer().beginWrite();
        }

        catch (const cxxtools::IOError&)
        {
            log_debug("first write failed, so connection is not active any more");

            _stream.clear();
            _stream.buffer().discard();
            _socket.beginConnect(_addrInfo);
        }
    }
    else
    {
        _socket.beginConnect(_addrInfo);
    }
}

void ClientImpl::wait(std::size_t msecs)
{
    _socket.wait(msecs);
}

void ClientImpl::sendRequest(const Request& request)
{
    log_debug("send request " << request.url());

    static const std::string contentLength = "Content-Length";
    static const std::string connection = "Connection";
    static const std::string date = "Date";
    static const std::string host = "Host";
    static const std::string authorization = "Authorization";

    _stream << request.method() << ' '
            << request.url() << " HTTP/"
            << request.header().httpVersionMajor() << '.'
            << request.header().httpVersionMinor() << "\r\n";

    for (RequestHeader::const_iterator it = request.header().begin();
        it != request.header().end(); ++it)
    {
        _stream << it->first << ": " << it->second << "\r\n";
    }

   if (!request.header().hasHeader(contentLength))
    {
        _stream << "Content-Length: " << request.bodySize() << "\r\n";
    }

    if (!request.header().hasHeader(connection))
    {
        _stream << "Connection: keep-alive\r\n";
    }

    if (!request.header().hasHeader(date))
    {
        _stream << "Date: " << MessageHeader::htdateCurrent() << "\r\n";
    }

    if (!request.header().hasHeader(host))
    {
        _stream << "Host: " << _addrInfo.host();
        unsigned short port = _addrInfo.port();
        if (port != 80)
            _stream << ':' << port;
        _stream << "\r\n";
    }

    if (!_username.empty() && !request.header().hasHeader(authorization))
    {
        std::ostringstream d;
        BasicTextOStream<char, char> b(d, new Base64Codec());
        b << _username
          << ':'
          << _password;
        b.terminate();
        log_debug("set Authorization to " << d.str());
        _stream << "Authorization: Basic " << d.str() << "\r\n";
    }

    _stream << "\r\n";

    log_debug("send body; " << request.bodySize() << " bytes");

    request.sendBody(_stream);
}

void ClientImpl::onConnect(net::TcpSocket& socket)
{
    try
    {
        log_trace("onConnect");
        socket.endConnect();
        sendRequest(*_request);

        log_debug("request sent - begin write");
        _stream.buffer().beginWrite();
    }
    catch (const std::exception& e)
    {
        _client->errorOccured(*_client, e);
    }
}

void ClientImpl::onErrorOccured(IODevice& socket)
{
    try
    {
        throw IOError( CXXTOOLS_ERROR_MSG("error occured in i/o-device") );
    }
    catch (const IOError& e)
    {
        _client->errorOccured(*_client, e);
    }
}

void ClientImpl::onOutput(StreamBuffer& sb)
{
    log_trace("ClientImpl::onOutput; out_avail=" << sb.out_avail());

    if( sb.out_avail() > 0 )
    {
        sb.beginWrite();
    }
    else
    {
        sb.beginRead();
        _client->requestSent(*_client);
        _parser.reset(true);
        _readHeader = true;
    }
}

void ClientImpl::onInput(StreamBuffer& sb)
{
    try
    {
        log_trace("ClientImpl::onInput; readHeader=" << _readHeader);

        if (_readHeader)
        {
            processHeaderAvailable(sb);
        }
        else
        {
            processBodyAvailable(sb);
        }
    }
    catch (const std::exception& e)
    {
        log_warn("error of type " << typeid(e).name() << " occured: " << e.what());

        _socket.close();

        // TODO propagate exception if signal errorOccured is not connected
        _client->errorOccured(*_client, e);
    }
}

void ClientImpl::processHeaderAvailable(StreamBuffer& sb)
{
    _parser.advance(sb);

    if (_parser.fail())
        throw std::runtime_error("http parser failed"); // TODO define exception class

    if( _parser.end() )
    {
        _chunkedEncoding = _replyHeader.chunkedTransferEncoding();

        _client->headerReceived(*_client);
        _readHeader = false;

        if (_chunkedEncoding)
        {
            log_debug("chunked transfer encoding used");

            _chunkedIStream.reset();

            if( sb.in_avail() > 0 )
            {
                processBodyAvailable(sb);
            }
            else
            {
                sb.beginRead();
            }
        }
        else
        {
            _contentLength = _replyHeader.contentLength();
            log_debug("header received - content-length=" << _contentLength);

            if (_contentLength > 0)
            {
                if( sb.in_avail() > 0 )
                {
                    processBodyAvailable(sb);
                }
                else
                {
                    sb.beginRead();
                }
            }
            else
            {
                _client->replyFinished(*_client);
            }
        }
    }
    else
    {
        sb.beginRead();
    }
}

void ClientImpl::processBodyAvailable(StreamBuffer& sb)
{
    log_trace("processBodyAvailable");

    if (_chunkedEncoding)
    {
        if (_chunkedIStream.rdbuf()->in_avail() > 0)
        {
            if (!_chunkedIStream.eod())
            {
                log_debug("read chunked encoding body");

                while (_chunkedIStream.rdbuf()->in_avail() > 0
                    && !_chunkedIStream.eod())
                {
                    log_debug("bodyAvailable");
                    _client->bodyAvailable(*_client);
                }

                log_debug("in_avail=" << _chunkedIStream.rdbuf()->in_avail() << " eod=" << _chunkedIStream.eod());
                if (_chunkedIStream.eod())
                {
                    _parser.readHeader();
                }
            }

            if (_chunkedIStream.eod() && sb.in_avail() > 0)
            {
                log_debug("read chunked encoding post headers");

                _parser.advance(sb);
                if (_parser.fail())
                    throw std::runtime_error("http parser failed"); // TODO define exception class

                if( _parser.end() )
                {
                    log_debug("reply finished");
                    _client->replyFinished(*_client);
                }
            }
        }

        if (!_chunkedIStream.eod() || !_parser.end())
        {
            log_debug("call beginRead");
            sb.beginRead();
        }
    }
    else
    {
        log_debug("content-length(pre)=" << _contentLength);

        while (_contentLength > 0 && sb.in_avail() > 0)
        {
            _contentLength -= _client->bodyAvailable(*_client); // TODO: may throw exception
            log_debug("content-length(post)=" << _contentLength);
        }

        if( _contentLength <= 0 )
        {
            log_debug("reply finished");
            _client->replyFinished(*_client);
        }
        else
        {
            sb.beginRead();
        }
    }
}

} // namespace http

} // namespace cxxtools
<commit_msg>bugfix: request after a unsuccessful request failed in http client<commit_after>/*
 * Copyright (C) 2009 by Marc Boris Duerner, Tommi Maekitalo
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "clientimpl.h"
#include <cxxtools/http/client.h>
#include "parser.h"
#include <cxxtools/ioerror.h>
#include <cxxtools/textstream.h>
#include <cxxtools/base64codec.h>
#include <sstream>

#include <cxxtools/log.h>

log_define("cxxtools.http.client.impl")

namespace cxxtools {

namespace http {

void ClientImpl::ParseEvent::onHttpReturn(unsigned ret, const std::string& text)
{
    _replyHeader.httpReturn(ret, text);
}

ClientImpl::ClientImpl(Client* client)
: _client(client)
, _parseEvent(_replyHeader)
, _parser(_parseEvent, true)
, _request(0)
, _stream(8192, true)
, _readHeader(true)
, _contentLength(0)
, _chunkedEncoding(false)
, _chunkedIStream(_stream.rdbuf())
{
    _stream.attachDevice(_socket);
    cxxtools::connect(_socket.connected, *this, &ClientImpl::onConnect);
    cxxtools::connect(_socket.errorOccured, *this, &ClientImpl::onErrorOccured);
    cxxtools::connect(_stream.buffer().outputReady, *this, &ClientImpl::onOutput);
    cxxtools::connect(_stream.buffer().inputReady, *this, &ClientImpl::onInput);
}

ClientImpl::ClientImpl(Client* client, const net::AddrInfo& addrinfo)
: _client(client)
, _parseEvent(_replyHeader)
, _parser(_parseEvent, true)
, _request(0)
, _addrInfo(addrinfo)
, _stream(8192, true)
, _readHeader(true)
, _contentLength(0)
, _chunkedEncoding(false)
, _chunkedIStream(_stream.rdbuf())
{
    _stream.attachDevice(_socket);
    cxxtools::connect(_socket.connected, *this, &ClientImpl::onConnect);
    cxxtools::connect(_socket.errorOccured, *this, &ClientImpl::onErrorOccured);
    cxxtools::connect(_stream.buffer().outputReady, *this, &ClientImpl::onOutput);
    cxxtools::connect(_stream.buffer().inputReady, *this, &ClientImpl::onInput);
}

ClientImpl::ClientImpl(Client* client, SelectorBase& selector, const net::AddrInfo& addrinfo)
: _client(client)
, _parseEvent(_replyHeader)
, _parser(_parseEvent, true)
, _request(0)
, _addrInfo(addrinfo)
, _stream(8192, true)
, _readHeader(true)
, _contentLength(0)
, _chunkedEncoding(false)
, _chunkedIStream(_stream.rdbuf())
{
    _stream.attachDevice(_socket);
    cxxtools::connect(_socket.connected, *this, &ClientImpl::onConnect);
    cxxtools::connect(_socket.errorOccured, *this, &ClientImpl::onErrorOccured);
    cxxtools::connect(_stream.buffer().outputReady, *this, &ClientImpl::onOutput);
    cxxtools::connect(_stream.buffer().inputReady, *this, &ClientImpl::onInput);
    setSelector(selector);
}

void ClientImpl::setSelector(SelectorBase& selector)
{
    selector.add(_socket);
}

void ClientImpl::reexecute(const Request& request)
{
    log_debug("reconnect");

    _stream.clear();
    _stream.buffer().discard();

    _socket.connect(_addrInfo);

    sendRequest(request);
    _stream.flush();
}

void ClientImpl::doparse()
{
    char ch;
    while (!_parser.end() && _stream.get(ch))
        _parser.parse(ch);

}

const ReplyHeader& ClientImpl::execute(const Request& request, std::size_t timeout)
{
    log_trace("execute request " << request.url());

    _replyHeader.clear();

    _socket.setTimeout(timeout);

    bool shouldReconnect = _socket.isConnected();
    if (!shouldReconnect)
    {
        log_debug("connect");
        _socket.connect(_addrInfo);
    }

    log_debug("send request");
    sendRequest(request);
    log_debug("flush stream");
    _stream.flush();

    log_debug("flush stream ready");
    if (!_stream && shouldReconnect)
    {
        // sending failed and we were not connected before, so try again
        reexecute(request);
        shouldReconnect = false;
    }

    if (!_stream)
        throw IOError( CXXTOOLS_ERROR_MSG("error sending HTTP request") );

    log_debug("read reply");

    _parser.reset(true);
    _readHeader = true;
    doparse();

    if (_parser.begin() && shouldReconnect)
    {
        // reading failed and we were not connected before, so try again
        reexecute(request);

        if (!_stream)
            throw IOError( CXXTOOLS_ERROR_MSG("error sending HTTP request") );

        doparse();
    }

    log_debug("reply ready");

    if (_stream.fail())
        throw IOError( CXXTOOLS_ERROR_MSG("failed to read HTTP reply") );

    if (_parser.fail())
        throw IOError( CXXTOOLS_ERROR_MSG("invalid HTTP reply") );

    if (!_parser.end())
        throw IOError( CXXTOOLS_ERROR_MSG("incomplete HTTP reply header") );

    return _replyHeader;
}

void ClientImpl::readBody(std::string& s)
{
    s.clear();

    _chunkedEncoding = _replyHeader.chunkedTransferEncoding();
    _chunkedIStream.reset();

    if (_chunkedEncoding)
    {
        log_debug("read body with chunked encoding");

        char ch;
        while (_chunkedIStream.get(ch))
            s += ch;

        log_debug("eod=" << _chunkedIStream.eod());

        if (_chunkedIStream.eod())
        {
            _parser.readHeader();
            doparse();

            if (_parser.fail())
                throw std::runtime_error("http parser failed"); // TODO define exception class
        }
        else
            throw std::runtime_error("chunked stream not complete");
    }
    else
    {
        unsigned n = _replyHeader.contentLength();

        log_debug("read body; content-size: " << n);

        s.reserve(n);

        char ch;
        while (n-- && _stream.get(ch))
            s += ch;

        if (_stream.fail())
            throw IOError( CXXTOOLS_ERROR_MSG("error reading HTTP reply body") );

        //log_debug("body read: \"" << s << '"');
    }

    if (!_replyHeader.keepAlive())
    {
        log_debug("close socket - no keep alive");
        _socket.close();
    }
    else
    {
        log_debug("do not close socket - keep alive");
    }
}

std::string ClientImpl::get(const std::string& url, std::size_t timeout)
{
    Request request(url);
    execute(request, timeout);
    return readBody();
}

void ClientImpl::beginExecute(const Request& request)
{
    _request = &request;
    _replyHeader.clear();
    if (_socket.isConnected())
    {
        sendRequest(*_request);
        try
        {
            _stream.buffer().beginWrite();
        }

        catch (const cxxtools::IOError&)
        {
            log_debug("first write failed, so connection is not active any more");

            _stream.clear();
            _stream.buffer().discard();
            _socket.beginConnect(_addrInfo);
        }
    }
    else
    {
        _socket.beginConnect(_addrInfo);
    }
}

void ClientImpl::wait(std::size_t msecs)
{
    _socket.wait(msecs);
}

void ClientImpl::sendRequest(const Request& request)
{
    log_debug("send request " << request.url());

    static const std::string contentLength = "Content-Length";
    static const std::string connection = "Connection";
    static const std::string date = "Date";
    static const std::string host = "Host";
    static const std::string authorization = "Authorization";

    _stream << request.method() << ' '
            << request.url() << " HTTP/"
            << request.header().httpVersionMajor() << '.'
            << request.header().httpVersionMinor() << "\r\n";

    for (RequestHeader::const_iterator it = request.header().begin();
        it != request.header().end(); ++it)
    {
        _stream << it->first << ": " << it->second << "\r\n";
    }

   if (!request.header().hasHeader(contentLength))
    {
        _stream << "Content-Length: " << request.bodySize() << "\r\n";
    }

    if (!request.header().hasHeader(connection))
    {
        _stream << "Connection: keep-alive\r\n";
    }

    if (!request.header().hasHeader(date))
    {
        _stream << "Date: " << MessageHeader::htdateCurrent() << "\r\n";
    }

    if (!request.header().hasHeader(host))
    {
        _stream << "Host: " << _addrInfo.host();
        unsigned short port = _addrInfo.port();
        if (port != 80)
            _stream << ':' << port;
        _stream << "\r\n";
    }

    if (!_username.empty() && !request.header().hasHeader(authorization))
    {
        std::ostringstream d;
        BasicTextOStream<char, char> b(d, new Base64Codec());
        b << _username
          << ':'
          << _password;
        b.terminate();
        log_debug("set Authorization to " << d.str());
        _stream << "Authorization: Basic " << d.str() << "\r\n";
    }

    _stream << "\r\n";

    log_debug("send body; " << request.bodySize() << " bytes");

    request.sendBody(_stream);
}

void ClientImpl::onConnect(net::TcpSocket& socket)
{
    try
    {
        log_trace("onConnect");
        socket.endConnect();
        sendRequest(*_request);

        log_debug("request sent - begin write");
        _stream.buffer().beginWrite();
    }
    catch (const std::exception& e)
    {
        _client->errorOccured(*_client, e);
    }
}

void ClientImpl::onErrorOccured(IODevice& socket)
{
    try
    {
        throw IOError( CXXTOOLS_ERROR_MSG("error occured in i/o-device") );
    }
    catch (const IOError& e)
    {
        _client->errorOccured(*_client, e);
    }
}

void ClientImpl::onOutput(StreamBuffer& sb)
{
    log_trace("ClientImpl::onOutput; out_avail=" << sb.out_avail());

    if( sb.out_avail() > 0 )
    {
        sb.beginWrite();
    }
    else
    {
        sb.beginRead();
        _client->requestSent(*_client);
        _parser.reset(true);
        _readHeader = true;
    }
}

void ClientImpl::onInput(StreamBuffer& sb)
{
    try
    {
        log_trace("ClientImpl::onInput; readHeader=" << _readHeader);

        if (_readHeader)
        {
            processHeaderAvailable(sb);
        }
        else
        {
            processBodyAvailable(sb);
        }
    }
    catch (const std::exception& e)
    {
        log_warn("error of type " << typeid(e).name() << " occured: " << e.what());

        _socket.close();

        // TODO propagate exception if signal errorOccured is not connected
        _client->errorOccured(*_client, e);
    }
}

void ClientImpl::processHeaderAvailable(StreamBuffer& sb)
{
    _parser.advance(sb);

    if (_parser.fail())
        throw std::runtime_error("http parser failed"); // TODO define exception class

    if( _parser.end() )
    {
        _chunkedEncoding = _replyHeader.chunkedTransferEncoding();

        _client->headerReceived(*_client);
        _readHeader = false;

        if (_chunkedEncoding)
        {
            log_debug("chunked transfer encoding used");

            _chunkedIStream.reset();

            if( sb.in_avail() > 0 )
            {
                processBodyAvailable(sb);
            }
            else
            {
                sb.beginRead();
            }
        }
        else
        {
            _contentLength = _replyHeader.contentLength();
            log_debug("header received - content-length=" << _contentLength);

            if (_contentLength > 0)
            {
                if( sb.in_avail() > 0 )
                {
                    processBodyAvailable(sb);
                }
                else
                {
                    sb.beginRead();
                }
            }
            else
            {
                _client->replyFinished(*_client);
            }
        }
    }
    else
    {
        sb.beginRead();
    }
}

void ClientImpl::processBodyAvailable(StreamBuffer& sb)
{
    log_trace("processBodyAvailable");

    if (_chunkedEncoding)
    {
        if (_chunkedIStream.rdbuf()->in_avail() > 0)
        {
            if (!_chunkedIStream.eod())
            {
                log_debug("read chunked encoding body");

                while (_chunkedIStream.rdbuf()->in_avail() > 0
                    && !_chunkedIStream.eod())
                {
                    log_debug("bodyAvailable");
                    _client->bodyAvailable(*_client);
                }

                log_debug("in_avail=" << _chunkedIStream.rdbuf()->in_avail() << " eod=" << _chunkedIStream.eod());
                if (_chunkedIStream.eod())
                {
                    _parser.readHeader();
                }
            }

            if (_chunkedIStream.eod() && sb.in_avail() > 0)
            {
                log_debug("read chunked encoding post headers");

                _parser.advance(sb);
                if (_parser.fail())
                    throw std::runtime_error("http parser failed"); // TODO define exception class

                if( _parser.end() )
                {
                    log_debug("reply finished");
                    _client->replyFinished(*_client);
                }
            }
        }

        if (!_chunkedIStream.eod() || !_parser.end())
        {
            log_debug("call beginRead");
            sb.beginRead();
        }
    }
    else
    {
        log_debug("content-length(pre)=" << _contentLength);

        while (_contentLength > 0 && sb.in_avail() > 0)
        {
            _contentLength -= _client->bodyAvailable(*_client); // TODO: may throw exception
            log_debug("content-length(post)=" << _contentLength);
        }

        if( _contentLength <= 0 )
        {
            log_debug("reply finished");
            _client->replyFinished(*_client);
        }
        else
        {
            sb.beginRead();
        }
    }
}

} // namespace http

} // namespace cxxtools
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "glrasterizer.h"
#include "glrglfw.h"
#include "shaders.h"

void init_program_to_texture_shader(glr_scene* scene)
{
	printf("init_program_and_shaders()\n");
	GLuint shaders [2];
	shaders[0] = glr_create_shader_from_string(
			GL_VERTEX_SHADER, texture_shader_vert_str);
	shaders[1] = glr_create_shader_from_string(
			GL_FRAGMENT_SHADER, texture_shader_frag_str);
	scene->program = glr_create_program(shaders, 2);
	glDeleteShader(shaders[0]);
	glDeleteShader(shaders[1]);
}

void init_frame_buffer(glr_scene* scene)
{
	printf("init_frame_buffer()\n");
	// for a framebuffer we don't actually care about the texture unit.
	// however, glr_init_texture will bind the unit before performing the
	// initialization for consistency. We can safely set a (usually illegal)
	// value of zero here so that the unit binding is basically a no op.
	scene->fb_rgb_target.unit = 0;
	scene->fb_f3v_target.unit = 0;
	glr_init_texture(&scene->fb_rgb_target);
	glr_init_texture(&scene->fb_f3v_target);
    // ask OpenGL to make us a framebuffer object for the fbo
	glGenFramebuffers(1, &scene->fbo);
    // init the two framebuffer textures
	glr_init_framebuffer(&scene->fbo, &scene->fb_rgb_target, GL_COLOR_ATTACHMENT0);
	glr_init_framebuffer(&scene->fbo, &scene->fb_f3v_target, GL_COLOR_ATTACHMENT1);
	// We set the RGB framebuffer to GL_COLOR_ATTACHMENT0 - anything rendered to
	// layout(location = 0) in the fragment shader will end up here.
	// The float framebuffer is attached to GL_COLOR_ATTACHMENT1 - anything rendered to
	// layout(location = 1) in the fragment shader will end up here.
	GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
	glr_register_draw_framebuffers(scene->fbo, 2, buffers);
	// now, the depth buffer
	GLuint depth_buffer;
	glGenRenderbuffers(1, &depth_buffer);
	glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT,
			scene->fb_rgb_target.width, scene->fb_rgb_target.height);
	glBindFramebuffer(GL_FRAMEBUFFER, scene->fbo);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
			GL_RENDERBUFFER, depth_buffer);
	// THIS BEING GL_DEPTH_COMPONENT means that the depth information at each
	// fragment will end up here. Note that we must manually set up the depth
	// buffer when using framebuffers.
	GLenum status;
	status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if(status != GL_FRAMEBUFFER_COMPLETE) {
		printf("Framebuffer error: 0x%04X\n", status);
		exit(EXIT_FAILURE);
	}
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	glr_check_error();
}

void render_texture_shader_to_fb(glr_scene* scene)
{
	printf("render_texture_shader_to_fb(...)\n");
	// call the init
	init(scene);

    // render to the framebuffer, and pull off the state
    glr_render_to_framebuffer(scene);

    // clear up our OpenGL state
	glr_destroy_vbos_on_trianglar_mesh(&(scene->mesh));
	glr_destroy_texture(&scene->mesh.texture);
}

void init(glr_scene* scene)
{
	printf("init()\n");
	glUseProgram(scene->program);
	glr_check_error();
	// now we have an instantiated glr_textured_mesh, we have to choose
	// some the OpenGL properties and set them. We decide that the vertices
	// should be bound to input 0 into the shader, while tcoords should be
	// input 1, and the float 3 vec is 2.
	scene->mesh.vertices.attribute_pointer = 0;
	scene->mesh.tcoords.attribute_pointer = 1;
	scene->mesh.f3v_data.attribute_pointer = 2;
	// assign the meshes texture to be on unit 1 and initialize the buffer for
	// it
	scene->mesh.texture.unit = 1;
	glr_init_vao(&scene->mesh);
	glr_check_error();
	glr_init_texture(&scene->mesh.texture);
	glr_check_error();
}

<commit_msg>Print to stderr instead of stdout<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "glrasterizer.h"
#include "glrglfw.h"
#include "shaders.h"

void init_program_to_texture_shader(glr_scene* scene)
{
	fprintf(stderr, "Initialise program and shaders\n");

	GLuint shaders [2];
	shaders[0] = glr_create_shader_from_string(
			GL_VERTEX_SHADER, texture_shader_vert_str);
	shaders[1] = glr_create_shader_from_string(
			GL_FRAGMENT_SHADER, texture_shader_frag_str);
	scene->program = glr_create_program(shaders, 2);
	glDeleteShader(shaders[0]);
	glDeleteShader(shaders[1]);
}

void init_frame_buffer(glr_scene* scene)
{
	fprintf(stderr, "Initialise frame buffer\n");
	// for a framebuffer we don't actually care about the texture unit.
	// however, glr_init_texture will bind the unit before performing the
	// initialization for consistency. We can safely set a (usually illegal)
	// value of zero here so that the unit binding is basically a no op.
	scene->fb_rgb_target.unit = 0;
	scene->fb_f3v_target.unit = 0;
	glr_init_texture(&scene->fb_rgb_target);
	glr_init_texture(&scene->fb_f3v_target);
    // ask OpenGL to make us a framebuffer object for the fbo
	glGenFramebuffers(1, &scene->fbo);
    // init the two framebuffer textures
	glr_init_framebuffer(&scene->fbo, &scene->fb_rgb_target, GL_COLOR_ATTACHMENT0);
	glr_init_framebuffer(&scene->fbo, &scene->fb_f3v_target, GL_COLOR_ATTACHMENT1);
	// We set the RGB framebuffer to GL_COLOR_ATTACHMENT0 - anything rendered to
	// layout(location = 0) in the fragment shader will end up here.
	// The float framebuffer is attached to GL_COLOR_ATTACHMENT1 - anything rendered to
	// layout(location = 1) in the fragment shader will end up here.
	GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
	glr_register_draw_framebuffers(scene->fbo, 2, buffers);
	// now, the depth buffer
	GLuint depth_buffer;
	glGenRenderbuffers(1, &depth_buffer);
	glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT,
			scene->fb_rgb_target.width, scene->fb_rgb_target.height);
	glBindFramebuffer(GL_FRAMEBUFFER, scene->fbo);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
			GL_RENDERBUFFER, depth_buffer);
	// THIS BEING GL_DEPTH_COMPONENT means that the depth information at each
	// fragment will end up here. Note that we must manually set up the depth
	// buffer when using framebuffers.
	GLenum status;
	status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if(status != GL_FRAMEBUFFER_COMPLETE) {
		printf("Framebuffer error: 0x%04X\n", status);
		exit(EXIT_FAILURE);
	}
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	glr_check_error();
}

void render_texture_shader_to_fb(glr_scene* scene)
{
	fprintf(stderr, "Render texture shader to frame buffer\n");

	// call the init
	init(scene);

    // render to the framebuffer, and pull off the state
    glr_render_to_framebuffer(scene);

    // clear up our OpenGL state
	glr_destroy_vbos_on_trianglar_mesh(&(scene->mesh));
	glr_destroy_texture(&scene->mesh.texture);
}

void init(glr_scene* scene)
{
	fprintf(stderr, "Initialise...\n");
	glUseProgram(scene->program);
	glr_check_error();
	// now we have an instantiated glr_textured_mesh, we have to choose
	// some the OpenGL properties and set them. We decide that the vertices
	// should be bound to input 0 into the shader, while tcoords should be
	// input 1, and the float 3 vec is 2.
	scene->mesh.vertices.attribute_pointer = 0;
	scene->mesh.tcoords.attribute_pointer = 1;
	scene->mesh.f3v_data.attribute_pointer = 2;
	// assign the meshes texture to be on unit 1 and initialize the buffer for
	// it
	scene->mesh.texture.unit = 1;
	glr_init_vao(&scene->mesh);
	glr_check_error();
	glr_init_texture(&scene->mesh.texture);
	glr_check_error();
}

<|endoftext|>


<commit_before>#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <stdlib.h>
#include <QtGlobal>
#include <QtWidgets>

int main(int argc, char *argv[])
{
    // Global menubar is broken for qt5 apps in Ubuntu Unity, see:
    // https://bugs.launchpad.net/ubuntu/+source/appmenu-qt5/+bug/1323853
    // This workaround enables a local menubar.
    qputenv("UBUNTU_MENUPROXY","0");

    // Don't write .pyc files.
    qputenv("PYTHONDONTWRITEBYTECODE", "1");

    QApplication app(argc, argv);

    QString app_dir = app.applicationDirPath();
    QString main_qml = "/qml/main.qml";
    QString path_prefix;
    QString url_prefix;

    app.setApplicationName("YubiKey Manager");
    app.setApplicationVersion(APP_VERSION);
    app.setOrganizationName("Yubico");
    app.setOrganizationDomain("com.yubico");

    QCommandLineParser parser;
    parser.setApplicationDescription("Cross-platform application for YubiKey configuration");
    parser.addHelpOption();
    parser.addVersionOption();
    parser.addOptions({
        {"log-level", QCoreApplication::translate("main", "Set log level to <LEVEL>"), QCoreApplication::translate("main", "LEVEL")},
        {"log-file", QCoreApplication::translate("main", "Print logs to <FILE> instead of standard output; ignored without --log-level"), QCoreApplication::translate("main", "FILE")},
    });

    parser.process(app);

    // A lock file is used, to ensure only one running instance at the time.
    QString tmpDir = QDir::tempPath();
    QLockFile lockFile(tmpDir + "/ykman-gui.lock");
    if(!lockFile.tryLock(100)) {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Warning);
        msgBox.setText("YubiKey Manager is already running.");
        msgBox.exec();
        return 1;
    }

    if (QFileInfo::exists(":" + main_qml)) {
        // Embedded resources
        path_prefix = ":";
        url_prefix = "qrc://";
    } else if (QFileInfo::exists(app_dir + main_qml)) {
        // Try relative to executable
        path_prefix = app_dir;
        url_prefix = app_dir;
    } else {  //Assume qml/main.qml in cwd.
        app_dir = ".";
        path_prefix = ".";
        url_prefix = ".";
    }

    app.setWindowIcon(QIcon(path_prefix + "/images/windowicon.png"));

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("appDir", app_dir);
    engine.rootContext()->setContextProperty("urlPrefix", url_prefix);
    engine.rootContext()->setContextProperty("appVersion", APP_VERSION);

    engine.load(QUrl(url_prefix + main_qml));

    if (parser.isSet("log-level")) {
        if (parser.isSet("log-file")) {
            QMetaObject::invokeMethod(engine.rootObjects().first(), "enableLoggingToFile", Q_ARG(QVariant, parser.value("log-level")), Q_ARG(QVariant, parser.value("log-file")));
        } else {
            QMetaObject::invokeMethod(engine.rootObjects().first(), "enableLogging", Q_ARG(QVariant, parser.value("log-level")));
        }
    } else {
        QMetaObject::invokeMethod(engine.rootObjects().first(), "disableLogging");
    }

    return app.exec();
}
<commit_msg>Rename variable parser to cliParser<commit_after>#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <stdlib.h>
#include <QtGlobal>
#include <QtWidgets>

int main(int argc, char *argv[])
{
    // Global menubar is broken for qt5 apps in Ubuntu Unity, see:
    // https://bugs.launchpad.net/ubuntu/+source/appmenu-qt5/+bug/1323853
    // This workaround enables a local menubar.
    qputenv("UBUNTU_MENUPROXY","0");

    // Don't write .pyc files.
    qputenv("PYTHONDONTWRITEBYTECODE", "1");

    QApplication app(argc, argv);

    QString app_dir = app.applicationDirPath();
    QString main_qml = "/qml/main.qml";
    QString path_prefix;
    QString url_prefix;

    app.setApplicationName("YubiKey Manager");
    app.setApplicationVersion(APP_VERSION);
    app.setOrganizationName("Yubico");
    app.setOrganizationDomain("com.yubico");

    QCommandLineParser cliParser;
    cliParser.setApplicationDescription("Cross-platform application for YubiKey configuration");
    cliParser.addHelpOption();
    cliParser.addVersionOption();
    cliParser.addOptions({
        {"log-level", QCoreApplication::translate("main", "Set log level to <LEVEL>"), QCoreApplication::translate("main", "LEVEL")},
        {"log-file", QCoreApplication::translate("main", "Print logs to <FILE> instead of standard output; ignored without --log-level"), QCoreApplication::translate("main", "FILE")},
    });

    cliParser.process(app);

    // A lock file is used, to ensure only one running instance at the time.
    QString tmpDir = QDir::tempPath();
    QLockFile lockFile(tmpDir + "/ykman-gui.lock");
    if(!lockFile.tryLock(100)) {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Warning);
        msgBox.setText("YubiKey Manager is already running.");
        msgBox.exec();
        return 1;
    }

    if (QFileInfo::exists(":" + main_qml)) {
        // Embedded resources
        path_prefix = ":";
        url_prefix = "qrc://";
    } else if (QFileInfo::exists(app_dir + main_qml)) {
        // Try relative to executable
        path_prefix = app_dir;
        url_prefix = app_dir;
    } else {  //Assume qml/main.qml in cwd.
        app_dir = ".";
        path_prefix = ".";
        url_prefix = ".";
    }

    app.setWindowIcon(QIcon(path_prefix + "/images/windowicon.png"));

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("appDir", app_dir);
    engine.rootContext()->setContextProperty("urlPrefix", url_prefix);
    engine.rootContext()->setContextProperty("appVersion", APP_VERSION);

    engine.load(QUrl(url_prefix + main_qml));

    if (cliParser.isSet("log-level")) {
        if (cliParser.isSet("log-file")) {
            QMetaObject::invokeMethod(engine.rootObjects().first(), "enableLoggingToFile", Q_ARG(QVariant, cliParser.value("log-level")), Q_ARG(QVariant, cliParser.value("log-file")));
        } else {
            QMetaObject::invokeMethod(engine.rootObjects().first(), "enableLogging", Q_ARG(QVariant, cliParser.value("log-level")));
        }
    } else {
        QMetaObject::invokeMethod(engine.rootObjects().first(), "disableLogging");
    }

    return app.exec();
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Manfeel
// manfeel@foxmail.com

#include <libsigrok4DSL/libsigrok.h>
#include <algorithm> //min/max
#include <iostream>
#include <Pothos/Framework.hpp>
#include <Poco/Logger.h>
#include <chrono>
#include <random>
#include "devicemanager.h"
#include "sigsession.h"
#include "blockingqueue.hpp"

using namespace std;
//char DS_RES_PATH[256];//="/usr/local/share/DSView/res/";

/***********************************************************************
 * |PothosDoc DSCope(Virtual Oscilloscope)
 *
 * The dscope source capture the waveform to an output sample stream.
 *
 * The dscope source will post a sample rate stream label named "rxRate"
 * on the first call to work() after activate() has been called.
 * Downstream blocks like the plotter widgets can consume this label
 * and use it to set internal parameters like the axis scaling.
 *
 * |category /DreamSourceLab
 * |category /Sources
 * |keywords dscope oscilloscope
 *
 *
 * |param sampRate[Sample Rate] The rate of audio samples.
 * |option [1M] 1e6
 * |option [2M] 2e6
 * |option [5M] 5e6
 * |option [10M] 10e6
 * |option [20M] 20e6
 * |option [50M] 50e6
 * |option [100M] 100e6
 * |option [200M] 200e6
 * |default 100e6
 * |units Sps
 * |widget ComboBox(editable=true)
 *
 * |param vdiv[Voltage Div] The rate of voltage.
 * |option [10mv] 10
 * |option [20mv] 20
 * |option [50mv] 50
 * |option [100mv] 100
 * |option [200mv] 200
 * |option [500mv] 500
 * |option [1v] 1000
 * |option [2v] 2000
 * |default 50
 * |units mv
 * |widget ComboBox(editable=true)
 *
 * |param logLvl[Debug Log Level]
 * |option [SR_LOG_NONE] 0
 * |option [SR_LOG_ERR]  1
 * |option [SR_LOG_WARN] 2
 * |option [SR_LOG_INFO] 3
 * |option [SR_LOG_DBG]  4
 * |option [SR_LOG_SPEW] 5
 * |default 2
 *
 * |param dtype[Data Type] The data type produced by the audio source.
 * |option [Float32] "float32"
 * |default "float32"
 * |preview disable
 *
 * |factory /dsl/dscope(dtype)
 * |setter setSamplerate(sampRate)
 * |setter setVdiv(vdiv)
 * |setter setLogLevel(logLvl)
 **********************************************************************/
class DscopeSource : public Pothos::Block {
protected:
    bool _sendLabel = true;
    struct sr_context *sr_ctx = NULL;
    DeviceManager *_device_manager = NULL;
    SigSession *_session = NULL;
    BlockingQueue<sr_datafeed_dso> *dso_queue = NULL;
    const string lvlStr[6] = {"NONE","ERROR","WARN","INFO","DEBUG","SPEW"};
public:
    DscopeSource(const Pothos::DType &dtype)
    {

        //this->registerCall(this, POTHOS_FCN_TUPLE(DscopeSource, setupDevice));
        this->registerCall(this, POTHOS_FCN_TUPLE(DscopeSource, setSamplerate));
        this->registerCall(this, POTHOS_FCN_TUPLE(DscopeSource, setVdiv));
        this->registerCall(this, POTHOS_FCN_TUPLE(DscopeSource, setLogLevel));

        this->setupOutput(0, dtype);
        //this->setupOutput(1, dtype);

        // Initialise libsigrok
        if (sr_init(&sr_ctx) != SR_OK) {
            throw Pothos::Exception(__func__, "ERROR: libsigrok init failed for the first time!");
        }
        // * |initializer setupDevice(dtype)
        dso_queue = new BlockingQueue<sr_datafeed_dso>();
        _device_manager = new DeviceManager(sr_ctx);
        _session = new SigSession(*_device_manager, *dso_queue);

        _session->set_default_device();
        if( _session->get_device()->name() != "DSCope") {
            cout << "ERROR: device DSCope not found!" << endl;
            destruct();
            throw Pothos::Exception(__func__, "ERROR: device DSCope not found!");
        }

        ds_trigger_init();

        //_session->register_hotplug_callback();
        //_session->start_hotplug_proc();

        _session->get_device()->set_ch_enable(1, false);
        _session->get_device()->set_limit_samples(2048);
    }

    ~DscopeSource() {
        destruct();
    }

    void destruct() {
        if(_session != NULL) {
            cout << "destructing session." << endl;
            delete _session;
        }
        if(_device_manager != NULL) {
            cout << "destructing device manager." << endl;
            delete _device_manager;
        }
        if(dso_queue != NULL) {
            cout << "destructing dso_queue." << endl;
            delete dso_queue;
        }
    }

    static Pothos::Block *make(const Pothos::DType &dtype) {
        return (Pothos::Block*)new DscopeSource(dtype);
    }

    void setVdiv(uint64_t vdiv) {
        _session->get_device()->set_voltage_div(0, vdiv);
    }

    void setSamplerate(uint64_t samplerate) {
        _session->get_device()->set_sample_rate(samplerate);
    }

    void setLogLevel(int logLvl) {
        cout<< __func__ << "(" << lvlStr[logLvl] << ")" << endl;
        sr_log_loglevel_set(logLvl);
    }

    void activate(void) {
        _session->start_capture(false);
    }

    void deactivate(void) {
        _session->stop_capture();
    }

    void work(void) {
        if (this->workInfo().minOutElements == 0) return;

        int  numFrames = _session->get_device()->get_sample_limit();
        numFrames = std::min<int>(numFrames, this->workInfo().minOutElements);
        auto outPort0 = this->output(0);
        auto buffer = outPort0->buffer().as<float*>();
        const size_t numElems = outPort0->elements();
        uint64_t vdiv = _session->get_device()->get_voltage_div(0);
        sr_datafeed_dso dso = dso_queue->take();

        for(uint64_t i=0;i<numElems;i++) {
            uint8_t b = ((uint8_t *)dso.data)[i];
            //buffer[i]=(127.5 - b) * 10 * vdiv / 256.0f;
            buffer[i]=(127.5 - b) * vdiv / 25.6f;
        }

        if (_sendLabel) {
            _sendLabel = false;
            const auto rate = _session->get_device()->get_sample_rate();
            Pothos::Label label("rxRate", rate, 0);
            for (auto port : this->outputs()) port->postLabel(label);
        }

        //not ready to produce because of backoff
        //if (_readyTime >= std::chrono::high_resolution_clock::now()) return this->yield();

        //produce buffer (all modes)
        outPort0->produce(numElems);
    }
};

static Pothos::BlockRegistry registerDscope("/dsl/dscope", &DscopeSource::make);
<commit_msg>meet a very weird bug: the destruction order is weird!<commit_after>// Copyright (c) 2017 Manfeel
// manfeel@foxmail.com

#include <libsigrok4DSL/libsigrok.h>
#include <algorithm> //min/max
#include <iostream>
#include <Pothos/Framework.hpp>
#include <Poco/Logger.h>
#include <chrono>
#include <random>
#include "devicemanager.h"
#include "sigsession.h"
#include "blockingqueue.hpp"

using namespace std;
//char DS_RES_PATH[256];//="/usr/local/share/DSView/res/";

/***********************************************************************
 * |PothosDoc DSCope(Virtual Oscilloscope)
 *
 * The dscope source capture the waveform to an output sample stream.
 *
 * The dscope source will post a sample rate stream label named "rxRate"
 * on the first call to work() after activate() has been called.
 * Downstream blocks like the plotter widgets can consume this label
 * and use it to set internal parameters like the axis scaling.
 *
 * |category /DreamSourceLab
 * |category /Sources
 * |keywords dscope oscilloscope
 *
 *
 * |param sampRate[Sample Rate] The rate of audio samples.
 * |option [1M] 1e6
 * |option [2M] 2e6
 * |option [5M] 5e6
 * |option [10M] 10e6
 * |option [20M] 20e6
 * |option [50M] 50e6
 * |option [100M] 100e6
 * |option [200M] 200e6
 * |default 100e6
 * |units Sps
 * |widget ComboBox(editable=true)
 *
 * |param vdiv[Voltage Div] The rate of voltage.
 * |option [10mv] 10
 * |option [20mv] 20
 * |option [50mv] 50
 * |option [100mv] 100
 * |option [200mv] 200
 * |option [500mv] 500
 * |option [1v] 1000
 * |option [2v] 2000
 * |default 50
 * |units mv
 * |widget ComboBox(editable=true)
 *
 * |param logLvl[Debug Log Level]
 * |option [SR_LOG_NONE] 0
 * |option [SR_LOG_ERR]  1
 * |option [SR_LOG_WARN] 2
 * |option [SR_LOG_INFO] 3
 * |option [SR_LOG_DBG]  4
 * |option [SR_LOG_SPEW] 5
 * |default 2
 *
 * |param dtype[Data Type] The data type produced by the audio source.
 * |option [Float32] "float32"
 * |default "float32"
 * |preview disable
 *
 * |factory /dsl/dscope(dtype)
 * |setter setSamplerate(sampRate)
 * |setter setVdiv(vdiv)
 * |setter setLogLevel(logLvl)
 **********************************************************************/
class DscopeSource : public Pothos::Block {
protected:
    bool _sendLabel = true;
    struct sr_context *sr_ctx = NULL;
    DeviceManager *_device_manager = NULL;
    SigSession *_session = NULL;
    BlockingQueue<sr_datafeed_dso> *dso_queue = NULL;
    const char* lvlStr[6] = {"NONE","ERROR","WARN","INFO","DEBUG","SPEW"};
public:
    DscopeSource(const Pothos::DType &dtype)
    {

        //this->registerCall(this, POTHOS_FCN_TUPLE(DscopeSource, setupDevice));
        this->registerCall(this, POTHOS_FCN_TUPLE(DscopeSource, setSamplerate));
        this->registerCall(this, POTHOS_FCN_TUPLE(DscopeSource, setVdiv));
        this->registerCall(this, POTHOS_FCN_TUPLE(DscopeSource, setLogLevel));

        this->setupOutput(0, dtype);
        //this->setupOutput(1, dtype);

        // Initialise libsigrok
        if (sr_init(&sr_ctx) != SR_OK) {
            throw Pothos::Exception(__func__, "ERROR: libsigrok init failed for the first time!");
        }
        // * |initializer setupDevice(dtype)
        dso_queue = new BlockingQueue<sr_datafeed_dso>();
        _device_manager = new DeviceManager(sr_ctx);
        _session = new SigSession(*_device_manager, *dso_queue);

        _session->set_default_device();

        if( _session->get_device()->name() != "DSCope") {
            cout << "ERROR: device DSCope not found!" << endl;
            destruct();
            throw Pothos::Exception(__func__, "ERROR: device DSCope not found!");
        }

        ds_trigger_init();

        //_session->register_hotplug_callback();
        //_session->start_hotplug_proc();

        _session->get_device()->set_ch_enable(1, false);
        _session->get_device()->set_limit_samples(2048);
    }

    ~DscopeSource() {
        destruct();
    }

    // IMPORTANT! the session must destruct last! or the eavluator thread will lock-up!
    void destruct() {
        if(dso_queue != NULL) {
            cout << "destructing dso_queue." << endl;
            delete dso_queue;
        }

        if(_device_manager != NULL) {
            cout << "destructing device manager." << endl;
            delete _device_manager;
        }

        if(_session != NULL) {
            cout << "destructing session." << endl;
            delete _session;
        }
    }

    static Pothos::Block *make(const Pothos::DType &dtype) {
        return (Pothos::Block*)new DscopeSource(dtype);
    }

    void setVdiv(uint64_t vdiv) {
        _session->get_device()->set_voltage_div(0, vdiv);
    }

    void setSamplerate(uint64_t samplerate) {
        _session->get_device()->set_sample_rate(samplerate);
    }

    void setLogLevel(int logLvl) {
        cout<< __func__ << "(" << lvlStr[logLvl] << ")" << endl;
        sr_log_loglevel_set(logLvl);
    }

    void activate(void) {
        _session->start_capture(false);
    }

    void deactivate(void) {
        _session->stop_capture();
    }

    void work(void) {
        if (this->workInfo().minOutElements == 0) return;

        int  numFrames = _session->get_device()->get_sample_limit();
        numFrames = std::min<int>(numFrames, this->workInfo().minOutElements);
        auto outPort0 = this->output(0);
        auto buffer = outPort0->buffer().as<float*>();
        const size_t numElems = outPort0->elements();
        uint64_t vdiv = _session->get_device()->get_voltage_div(0);
        sr_datafeed_dso dso = dso_queue->take();

        for(uint64_t i=0;i<numElems;i++) {
            uint8_t b = ((uint8_t *)dso.data)[i];
            //buffer[i]=(127.5 - b) * 10 * vdiv / 256.0f;
            buffer[i]=(127.5 - b) * vdiv / 25.6f;
        }

        if (_sendLabel) {
            _sendLabel = false;
            const auto rate = _session->get_device()->get_sample_rate();
            Pothos::Label label("rxRate", rate, 0);
            for (auto port : this->outputs()) port->postLabel(label);
        }

        //not ready to produce because of backoff
        //if (_readyTime >= std::chrono::high_resolution_clock::now()) return this->yield();

        //produce buffer (all modes)
        outPort0->produce(numElems);
    }
};

static Pothos::BlockRegistry registerDscope("/dsl/dscope", &DscopeSource::make);
<|endoftext|>