<commit_before>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */
#include <signal.h>
#include "php_module.h"
#include <Poco/Path.h>

#ifdef ZTS
void ***tsrm_ls;
#endif

namespace kroll
{
	KROLL_MODULE(PHPModule, STRING(MODULE_NAME), STRING(MODULE_VERSION));
	static Logger* logger = Logger::Get("PHPModule");
	const static std::string phpSuffix("module.php");
	static bool buffering = false;

	PHPModule* PHPModule::instance_ = NULL;
	std::ostringstream PHPModule::buffer;
	std::string PHPModule::mimeType("text/html");

	static int UnbufferedWrite(const char *, unsigned int TSRMLS_DC);
	static void SetIniDefault(HashTable*, const char*, const char*);
	static void IniDefaults(HashTable*);
	static void LogMessage(char*);
	static int HeaderHandler(sapi_header_struct*, sapi_header_op_enum,
		sapi_headers_struct* TSRMLS_DC);

	void PHPModule::Initialize()
	{
		PHPModule::instance_ = this;
		int argc = 1;
		char *argv[2] = { "php_kroll", NULL };

		php_embed_module.ub_write = UnbufferedWrite;
		php_embed_module.log_message = LogMessage;
		php_embed_module.ini_defaults = IniDefaults;
		php_embed_module.header_handler = HeaderHandler;
		php_embed_init(argc, argv PTSRMLS_CC);

		PHPUtils::InitializePHPKrollClasses();
		this->InitializeBinding();
		host->AddModuleProvider(this);

		std::string resourcesPath(host->GetApplication()->GetResourcesPath());
		zend_alter_ini_entry("include_path", sizeof("include_path"),
			(char*) resourcesPath.c_str(), resourcesPath.size() - 1,
			ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
	}

	/*static*/
	void PHPModule::SetBuffering(bool newBuffering)
	{
		if (buffering)
		{
			buffer.str("");
		}
		buffering = newBuffering;
	}

	void PHPModule::Stop()
	{
		PHPModule::instance_ = NULL;

		SharedKObject global = this->host->GetGlobalObject();
		Script::GetInstance()->RemoveScriptEvaluator(this->binding);
		global->Set("PHP", Value::Undefined);
		this->binding->Set("evaluate", Value::Undefined);
		this->binding = 0;
		PHPModule::instance_ = 0;

		php_embed_shutdown(TSRMLS_C);
	}

	void PHPModule::InitializeBinding()
	{
		PHPModule::mimeType = SG(default_mimetype);

		SharedKObject global = this->host->GetGlobalObject();
		this->binding = new PHPEvaluator();
		global->Set("PHP", Value::NewObject(this->binding));
		Script::GetInstance()->AddScriptEvaluator(this->binding);

		zval *titaniumValue = PHPUtils::ToPHPValue(Value::NewObject(global));
		ZEND_SET_SYMBOL(&EG(symbol_table), PRODUCT_NAME, titaniumValue);
	}

	bool PHPModule::IsModule(std::string& path)
	{
		return (path.substr(path.length()-phpSuffix.length()) == phpSuffix);
	}

	Module* PHPModule::CreateModule(std::string& path)
	{
		zend_first_try
		{
			std::string includeScript = "include '" + path + "';";
			if (SUCCESS != zend_eval_string((char *) includeScript.c_str(),
				NULL, (char *) path.c_str() TSRMLS_CC))
				logger->Error("Error evaluating module at path: %s", path.c_str());
		}
		zend_catch
		{
			logger->Error("Error evaluating module at path: %s", path.c_str());
		}
		zend_end_try();

		Poco::Path p(path);
		std::string name(p.getBaseName());
		std::string moduledir(p.makeParent().toString());
		logger->Info("Loading PHP module name=%s path=%s", name.c_str(), path.c_str());

		return new PHPModuleInstance(host, path, moduledir, name);
	}

	static int UnbufferedWrite(const char *str, unsigned int length TSRMLS_DC)
	{
		std::string string(str, length);
		std::ostringstream& buffer = PHPModule::GetBuffer();

		// This shouldn't need to be thread safe right?
		if (buffering)
		{
			buffer << string;
		}
		else
		{
			logger->Info(string.c_str());
		}
		return length;
	}

	static void SetIniDefault(HashTable* config, const char* name, const char* value)
	{
		// Forgive me Martin, borrowed from php_cli.c line 409
		// Thou are forgiven.
		zval tmp;
		Z_SET_REFCOUNT(tmp, 0);
		Z_UNSET_ISREF(tmp);
		ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0);
		zend_hash_update(config, name, sizeof(name), &tmp, sizeof(zval), NULL);
	}

	static void IniDefaults(HashTable* configuration)
	{
		SetIniDefault(configuration, "display_errors", "1");
	}

	static void LogMessage(char* message)
	{
		logger->Debug(message);
	}

	static int HeaderHandler(sapi_header_struct* sapiHeader,
		sapi_header_op_enum op, sapi_headers_struct* sapiHeaders TSRMLS_DC)
	{
		if (sapiHeaders && sapiHeaders->mimetype)
		{
			std::string& mimeType = PHPModule::GetMimeType();
			mimeType = sapiHeaders->mimetype;
		}
		return op;
	}
}
<commit_msg>Fix off-by-one size error in PHP modules initialization.<commit_after>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */
#include <signal.h>
#include "php_module.h"
#include <Poco/Path.h>

#ifdef ZTS
void ***tsrm_ls;
#endif

namespace kroll
{
	KROLL_MODULE(PHPModule, STRING(MODULE_NAME), STRING(MODULE_VERSION));
	static Logger* logger = Logger::Get("PHPModule");
	const static std::string phpSuffix("module.php");
	static bool buffering = false;

	PHPModule* PHPModule::instance_ = NULL;
	std::ostringstream PHPModule::buffer;
	std::string PHPModule::mimeType("text/html");

	static int UnbufferedWrite(const char *, unsigned int TSRMLS_DC);
	static void SetIniDefault(HashTable*, const char*, const char*);
	static void IniDefaults(HashTable*);
	static void LogMessage(char*);
	static int HeaderHandler(sapi_header_struct*, sapi_header_op_enum,
		sapi_headers_struct* TSRMLS_DC);

	void PHPModule::Initialize()
	{
		PHPModule::instance_ = this;
		int argc = 1;
		char *argv[2] = { "php_kroll", NULL };

		php_embed_module.ub_write = UnbufferedWrite;
		php_embed_module.log_message = LogMessage;
		php_embed_module.ini_defaults = IniDefaults;
		php_embed_module.header_handler = HeaderHandler;
		php_embed_init(argc, argv PTSRMLS_CC);

		PHPUtils::InitializePHPKrollClasses();
		this->InitializeBinding();
		host->AddModuleProvider(this);

		std::string resourcesPath(host->GetApplication()->GetResourcesPath());
		zend_alter_ini_entry("include_path", sizeof("include_path"),
			(char*) resourcesPath.c_str(), resourcesPath.size(),
			ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
	}

	/*static*/
	void PHPModule::SetBuffering(bool newBuffering)
	{
		if (buffering)
		{
			buffer.str("");
		}
		buffering = newBuffering;
	}

	void PHPModule::Stop()
	{
		PHPModule::instance_ = NULL;

		SharedKObject global = this->host->GetGlobalObject();
		Script::GetInstance()->RemoveScriptEvaluator(this->binding);
		global->Set("PHP", Value::Undefined);
		this->binding->Set("evaluate", Value::Undefined);
		this->binding = 0;
		PHPModule::instance_ = 0;

		php_embed_shutdown(TSRMLS_C);
	}

	void PHPModule::InitializeBinding()
	{
		PHPModule::mimeType = SG(default_mimetype);

		SharedKObject global = this->host->GetGlobalObject();
		this->binding = new PHPEvaluator();
		global->Set("PHP", Value::NewObject(this->binding));
		Script::GetInstance()->AddScriptEvaluator(this->binding);

		zval *titaniumValue = PHPUtils::ToPHPValue(Value::NewObject(global));
		ZEND_SET_SYMBOL(&EG(symbol_table), PRODUCT_NAME, titaniumValue);
	}

	bool PHPModule::IsModule(std::string& path)
	{
		return (path.substr(path.length()-phpSuffix.length()) == phpSuffix);
	}

	Module* PHPModule::CreateModule(std::string& path)
	{
		zend_first_try
		{
			std::string includeScript = "include '" + path + "';";
			if (SUCCESS != zend_eval_string((char *) includeScript.c_str(),
				NULL, (char *) path.c_str() TSRMLS_CC))
				logger->Error("Error evaluating module at path: %s", path.c_str());
		}
		zend_catch
		{
			logger->Error("Error evaluating module at path: %s", path.c_str());
		}
		zend_end_try();

		Poco::Path p(path);
		std::string name(p.getBaseName());
		std::string moduledir(p.makeParent().toString());
		logger->Info("Loading PHP module name=%s path=%s", name.c_str(), path.c_str());

		return new PHPModuleInstance(host, path, moduledir, name);
	}

	static int UnbufferedWrite(const char *str, unsigned int length TSRMLS_DC)
	{
		std::string string(str, length);
		std::ostringstream& buffer = PHPModule::GetBuffer();

		// This shouldn't need to be thread safe right?
		if (buffering)
		{
			buffer << string;
		}
		else
		{
			logger->Info(string.c_str());
		}
		return length;
	}

	static void SetIniDefault(HashTable* config, const char* name, const char* value)
	{
		// Forgive me Martin, borrowed from php_cli.c line 409
		// Thou are forgiven.
		zval tmp;
		Z_SET_REFCOUNT(tmp, 0);
		Z_UNSET_ISREF(tmp);
		ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0);
		zend_hash_update(config, name, sizeof(name), &tmp, sizeof(zval), NULL);
	}

	static void IniDefaults(HashTable* configuration)
	{
		SetIniDefault(configuration, "display_errors", "1");
	}

	static void LogMessage(char* message)
	{
		logger->Debug(message);
	}

	static int HeaderHandler(sapi_header_struct* sapiHeader,
		sapi_header_op_enum op, sapi_headers_struct* sapiHeaders TSRMLS_DC)
	{
		if (sapiHeaders && sapiHeaders->mimetype)
		{
			std::string& mimeType = PHPModule::GetMimeType();
			mimeType = sapiHeaders->mimetype;
		}
		return op;
	}
}
<|endoftext|>


<commit_before>/* Copyright 2016 kunming.xie
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "gtest/gtest.h"
#include "base/string16.h"

TEST(char16, empty)
{
}
<commit_msg>delete unused test case<commit_after><|endoftext|>


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

#include "TestPool.hxx"
#include "GrowingBuffer.hxx"
#include "direct.hxx"
#include "istream_gb.hxx"
#include "istream/istream.hxx"
#include "istream/Pointer.hxx"
#include "istream/UnusedPtr.hxx"
#include "fb_pool.hxx"
#include "util/ConstBuffer.hxx"
#include "util/WritableBuffer.hxx"

#include <gtest/gtest.h>

#include <string.h>
#include <stdio.h>

struct Context final : IstreamHandler {
    struct pool *pool;
    bool got_data = false, eof = false, abort = false, closed = false;
    IstreamPointer abort_istream;

    explicit Context(struct pool &_pool)
        :pool(&_pool), abort_istream(nullptr) {}

    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    void OnEof() noexcept override;
    void OnError(std::exception_ptr ep) noexcept override;
};

/*
 * istream handler
 *
 */

size_t
Context::OnData(gcc_unused const void *data, size_t length)
{
    got_data = true;

    if (abort_istream.IsDefined()) {
        closed = true;
        abort_istream.ClearAndClose();
        pool_unref(pool);
        return 0;
    }

    return length;
}

void
Context::OnEof() noexcept
{
    eof = true;

    pool_unref(pool);
}

void
Context::OnError(std::exception_ptr) noexcept
{
    abort = true;

    pool_unref(pool);
}

/*
 * utils
 *
 */

static void
istream_read_expect(Context *ctx, IstreamPointer &istream)
{
    ASSERT_FALSE(ctx->eof);

    ctx->got_data = false;

    istream.Read();
    ASSERT_TRUE(ctx->eof || ctx->got_data);
}

static void
run_istream_ctx(Context *ctx, struct pool *pool, Istream *_istream)
{
    gcc_unused off_t a1 = _istream->GetAvailable(false);
    gcc_unused off_t a2 = _istream->GetAvailable(true);

    IstreamPointer istream(*_istream, *ctx);

#ifndef NO_GOT_DATA_ASSERT
    while (!ctx->eof)
        istream_read_expect(ctx, istream);
#else
    for (int i = 0; i < 1000 && !ctx->eof; ++i)
        istream->Read();
#endif

    if (!ctx->eof && !ctx->abort)
        istream.Close();

    if (!ctx->eof) {
        pool_trash(pool);
        pool_unref(pool);
    }

    pool_commit();
}

static void
run_istream(struct pool *pool, Istream *istream)
{
    Context ctx(*pool);
    run_istream_ctx(&ctx, pool, istream);
}

static Istream *
create_test(struct pool *pool)
{
    GrowingBuffer gb;
    gb.Write("foo");
    return istream_gb_new(*pool, std::move(gb)).Steal();
}

static Istream *
create_empty(struct pool *pool)
{
    GrowingBuffer gb;
    return istream_gb_new(*pool, std::move(gb)).Steal();
}

static bool
Equals(WritableBuffer<void> a, const char *b)
{
    return a.size == strlen(b) && memcmp(a.data, b, a.size) == 0;
}

/*
 * tests
 *
 */

/** normal run */
TEST(GrowingBufferTest, Normal)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    auto *istream = create_test(pool);
    run_istream(&pool.Steal(), istream);
}

/** empty input */
TEST(GrowingBufferTest, Empty)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    auto *istream = create_empty(pool);
    run_istream(&pool.Steal(), istream);
}

/** first buffer is too small, empty */
TEST(GrowingBufferTest, FirstEmpty)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    GrowingBuffer buffer;

    buffer.Write("0123456789abcdefg");

    ASSERT_EQ(buffer.GetSize(), 17);
    ASSERT_TRUE(Equals(buffer.Dup(pool), "0123456789abcdefg"));

    GrowingBufferReader reader(std::move(buffer));
    auto x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, 17);

    reader.Consume(x.size);
}

/** test growing_buffer_reader_skip() */
TEST(GrowingBufferTest, Skip)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;
    GrowingBuffer buffer;

    buffer.Write("0123");
    buffer.Write("4567");
    buffer.Write("89ab");
    buffer.Write("cdef");

    ASSERT_EQ(buffer.GetSize(), 16);
    ASSERT_TRUE(Equals(buffer.Dup(pool), "0123456789abcdef"));

    constexpr size_t buffer_size = 8192 - 2 * sizeof(void*) - 2 * sizeof(size_t);

    static char zero[buffer_size * 2];
    buffer.Write(zero, sizeof(zero));
    ASSERT_EQ(buffer.GetSize(), 16 + buffer_size * 2);

    GrowingBufferReader reader(std::move(buffer));
    reader.Skip(buffer_size - 2);

    auto x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, 2);
    reader.Consume(1);

    reader.Skip(5);

    x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, buffer_size - 4);
    reader.Consume(4);

    x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, buffer_size - 8);

    reader.Skip(buffer_size);

    x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, 8);

    reader.Skip(8);

    x = reader.Read();
    ASSERT_TRUE(x.IsNull());
}

/** test reading the head while appending to the tail */
TEST(GrowingBufferTest, ConcurrentRW)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    GrowingBuffer buffer;

    buffer.Write("0123");
    buffer.Write("4567");
    buffer.Write("89ab");

    ASSERT_EQ(buffer.GetSize(), 12);
    ASSERT_TRUE(Equals(buffer.Dup(pool), "0123456789ab"));

    buffer.Skip(12);
    ASSERT_TRUE(buffer.IsEmpty());
    ASSERT_EQ(buffer.GetSize(), 0);

    buffer.Write("cdef");

    ASSERT_FALSE(buffer.IsEmpty());
    ASSERT_EQ(buffer.GetSize(),4);
    ASSERT_TRUE(Equals(buffer.Dup(pool), "cdef"));

    auto x = buffer.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, 4);
}

/** abort without handler */
TEST(GrowingBufferTest, AbortWithoutHandler)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    auto *istream = create_test(pool);
    istream->CloseUnused();
}

/** abort with handler */
TEST(GrowingBufferTest, AbortWithHandler)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;
    Context ctx(pool.Steal());

    Istream *istream = create_test(ctx.pool);
    istream->SetHandler(ctx);

    istream->Close();
    pool_unref(ctx.pool);

    ASSERT_FALSE(ctx.abort);
}

/** abort in handler */
TEST(GrowingBufferTest, AbortInHandler)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;
    Context ctx(pool.Steal());

    ctx.abort_istream.Set(*create_test(ctx.pool), ctx);

    while (!ctx.eof && !ctx.abort && !ctx.closed)
        istream_read_expect(&ctx, ctx.abort_istream);

    ASSERT_FALSE(ctx.abort_istream.IsDefined());
    ASSERT_FALSE(ctx.abort);
    ASSERT_TRUE(ctx.closed);
}
<commit_msg>test/t_growing_buffer: use class UnusedIstreamPtr<commit_after>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "TestPool.hxx"
#include "GrowingBuffer.hxx"
#include "direct.hxx"
#include "istream_gb.hxx"
#include "istream/istream.hxx"
#include "istream/Pointer.hxx"
#include "istream/UnusedPtr.hxx"
#include "fb_pool.hxx"
#include "util/ConstBuffer.hxx"
#include "util/WritableBuffer.hxx"

#include <gtest/gtest.h>

#include <string.h>
#include <stdio.h>

struct Context final : IstreamHandler {
    struct pool *pool;
    bool got_data = false, eof = false, abort = false, closed = false;
    IstreamPointer abort_istream;

    explicit Context(struct pool &_pool)
        :pool(&_pool), abort_istream(nullptr) {}

    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    void OnEof() noexcept override;
    void OnError(std::exception_ptr ep) noexcept override;
};

/*
 * istream handler
 *
 */

size_t
Context::OnData(gcc_unused const void *data, size_t length)
{
    got_data = true;

    if (abort_istream.IsDefined()) {
        closed = true;
        abort_istream.ClearAndClose();
        pool_unref(pool);
        return 0;
    }

    return length;
}

void
Context::OnEof() noexcept
{
    eof = true;

    pool_unref(pool);
}

void
Context::OnError(std::exception_ptr) noexcept
{
    abort = true;

    pool_unref(pool);
}

/*
 * utils
 *
 */

static void
istream_read_expect(Context *ctx, IstreamPointer &istream)
{
    ASSERT_FALSE(ctx->eof);

    ctx->got_data = false;

    istream.Read();
    ASSERT_TRUE(ctx->eof || ctx->got_data);
}

static void
run_istream_ctx(Context *ctx, struct pool *pool, UnusedIstreamPtr _istream)
{
    gcc_unused off_t a1 = _istream.GetAvailable(false);
    gcc_unused off_t a2 = _istream.GetAvailable(true);

    IstreamPointer istream(std::move(_istream), *ctx);

#ifndef NO_GOT_DATA_ASSERT
    while (!ctx->eof)
        istream_read_expect(ctx, istream);
#else
    for (int i = 0; i < 1000 && !ctx->eof; ++i)
        istream->Read();
#endif

    if (!ctx->eof && !ctx->abort)
        istream.Close();

    if (!ctx->eof) {
        pool_trash(pool);
        pool_unref(pool);
    }

    pool_commit();
}

static void
run_istream(struct pool *pool, UnusedIstreamPtr istream)
{
    Context ctx(*pool);
    run_istream_ctx(&ctx, pool, std::move(istream));
}

static UnusedIstreamPtr
create_test(struct pool *pool)
{
    GrowingBuffer gb;
    gb.Write("foo");
    return istream_gb_new(*pool, std::move(gb));
}

static UnusedIstreamPtr
create_empty(struct pool *pool)
{
    GrowingBuffer gb;
    return istream_gb_new(*pool, std::move(gb));
}

static bool
Equals(WritableBuffer<void> a, const char *b)
{
    return a.size == strlen(b) && memcmp(a.data, b, a.size) == 0;
}

/*
 * tests
 *
 */

/** normal run */
TEST(GrowingBufferTest, Normal)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    run_istream(&pool.Steal(), create_test(pool));
}

/** empty input */
TEST(GrowingBufferTest, Empty)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    run_istream(&pool.Steal(), create_empty(pool));
}

/** first buffer is too small, empty */
TEST(GrowingBufferTest, FirstEmpty)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    GrowingBuffer buffer;

    buffer.Write("0123456789abcdefg");

    ASSERT_EQ(buffer.GetSize(), 17);
    ASSERT_TRUE(Equals(buffer.Dup(pool), "0123456789abcdefg"));

    GrowingBufferReader reader(std::move(buffer));
    auto x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, 17);

    reader.Consume(x.size);
}

/** test growing_buffer_reader_skip() */
TEST(GrowingBufferTest, Skip)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;
    GrowingBuffer buffer;

    buffer.Write("0123");
    buffer.Write("4567");
    buffer.Write("89ab");
    buffer.Write("cdef");

    ASSERT_EQ(buffer.GetSize(), 16);
    ASSERT_TRUE(Equals(buffer.Dup(pool), "0123456789abcdef"));

    constexpr size_t buffer_size = 8192 - 2 * sizeof(void*) - 2 * sizeof(size_t);

    static char zero[buffer_size * 2];
    buffer.Write(zero, sizeof(zero));
    ASSERT_EQ(buffer.GetSize(), 16 + buffer_size * 2);

    GrowingBufferReader reader(std::move(buffer));
    reader.Skip(buffer_size - 2);

    auto x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, 2);
    reader.Consume(1);

    reader.Skip(5);

    x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, buffer_size - 4);
    reader.Consume(4);

    x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, buffer_size - 8);

    reader.Skip(buffer_size);

    x = reader.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, 8);

    reader.Skip(8);

    x = reader.Read();
    ASSERT_TRUE(x.IsNull());
}

/** test reading the head while appending to the tail */
TEST(GrowingBufferTest, ConcurrentRW)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    GrowingBuffer buffer;

    buffer.Write("0123");
    buffer.Write("4567");
    buffer.Write("89ab");

    ASSERT_EQ(buffer.GetSize(), 12);
    ASSERT_TRUE(Equals(buffer.Dup(pool), "0123456789ab"));

    buffer.Skip(12);
    ASSERT_TRUE(buffer.IsEmpty());
    ASSERT_EQ(buffer.GetSize(), 0);

    buffer.Write("cdef");

    ASSERT_FALSE(buffer.IsEmpty());
    ASSERT_EQ(buffer.GetSize(),4);
    ASSERT_TRUE(Equals(buffer.Dup(pool), "cdef"));

    auto x = buffer.Read();
    ASSERT_FALSE(x.IsNull());
    ASSERT_EQ(x.size, 4);
}

/** abort without handler */
TEST(GrowingBufferTest, AbortWithoutHandler)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;

    auto istream = create_test(pool);
    istream.Clear();
}

/** abort with handler */
TEST(GrowingBufferTest, AbortWithHandler)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;
    Context ctx(pool.Steal());

    Istream *istream = create_test(ctx.pool).Steal();
    istream->SetHandler(ctx);

    istream->Close();
    pool_unref(ctx.pool);

    ASSERT_FALSE(ctx.abort);
}

/** abort in handler */
TEST(GrowingBufferTest, AbortInHandler)
{
    const ScopeFbPoolInit fb_pool_init;
    TestPool pool;
    Context ctx(pool.Steal());

    ctx.abort_istream.Set(create_test(ctx.pool), ctx);

    while (!ctx.eof && !ctx.abort && !ctx.closed)
        istream_read_expect(&ctx, ctx.abort_istream);

    ASSERT_FALSE(ctx.abort_istream.IsDefined());
    ASSERT_FALSE(ctx.abort);
    ASSERT_TRUE(ctx.closed);
}
<|endoftext|>


<commit_before>#include "RootPool.hxx"
#include "growing_buffer.hxx"
#include "direct.hxx"
#include "istream_gb.hxx"
#include "istream/istream.hxx"
#include "event/Base.hxx"
#include "util/ConstBuffer.hxx"

#include <glib.h>

#include <stdio.h>

struct Context final : IstreamHandler {
    struct pool *pool;
    bool got_data = false, eof = false, abort = false, closed = false;
    Istream *abort_istream = nullptr;

    explicit Context(struct pool &_pool):pool(&_pool) {}

    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    void OnEof() override;
    void OnError(GError *error) override;
};

/*
 * istream handler
 *
 */

size_t
Context::OnData(gcc_unused const void *data, size_t length)
{
    got_data = true;

    if (abort_istream != nullptr) {
        closed = true;
        istream_free(&abort_istream);
        pool_unref(pool);
        return 0;
    }

    return length;
}

void
Context::OnEof()
{
    eof = true;

    pool_unref(pool);
}

void
Context::OnError(GError *error)
{
    g_error_free(error);

    abort = true;

    pool_unref(pool);
}

/*
 * utils
 *
 */

static int
istream_read_event(Istream *istream)
{
    istream->Read();
    return event_loop(EVLOOP_ONCE|EVLOOP_NONBLOCK);
}

static void
istream_read_expect(Context *ctx, Istream *istream)
{
    int ret;

    assert(!ctx->eof);

    ctx->got_data = false;

    ret = istream_read_event(istream);
    assert(ctx->eof || ctx->got_data || ret == 0);

    /* give istream_later another chance to breathe */
    event_loop(EVLOOP_ONCE|EVLOOP_NONBLOCK);
}

static void
run_istream_ctx(Context *ctx, struct pool *pool, Istream *istream)
{
    gcc_unused off_t a1 = istream->GetAvailable(false);
    gcc_unused off_t a2 = istream->GetAvailable(true);

    istream->SetHandler(*ctx);

#ifndef NO_GOT_DATA_ASSERT
    while (!ctx->eof)
        istream_read_expect(ctx, istream);
#else
    for (int i = 0; i < 1000 && !ctx->eof; ++i)
           istream_read_event(istream);
#endif

    if (!ctx->eof) {
        pool_trash(pool);
        pool_unref(pool);
    }

    pool_commit();
}

static void
run_istream(struct pool *pool, Istream *istream)
{
    Context ctx(*pool);
    run_istream_ctx(&ctx, pool, istream);
}

static Istream *
create_test(struct pool *pool)
{
    GrowingBuffer *gb = growing_buffer_new(pool, 64);
    growing_buffer_write_string(gb, "foo");
    return istream_gb_new(*pool, *gb);
}

static Istream *
create_empty(struct pool *pool)
{
    GrowingBuffer *gb = growing_buffer_new(pool, 64);
    return istream_gb_new(*pool, *gb);
}

/*
 * tests
 *
 */

/** normal run */
static void
test_normal(struct pool *pool)
{
    Istream *istream;

    pool = pool_new_linear(pool, "test", 8192);
    istream = create_test(pool);

    run_istream(pool, istream);
}

/** empty input */
static void
test_empty(struct pool *pool)
{
    Istream *istream;

    pool = pool_new_linear(pool, "test", 8192);
    istream = create_empty(pool);

    run_istream(pool, istream);
}

/** first buffer is too small, empty */
static void
test_first_empty(struct pool *pool)
{
    pool = pool_new_linear(pool, "test", 8192);
    GrowingBuffer *buffer = growing_buffer_new(pool, 16);
    GrowingBufferReader reader(*buffer);

    growing_buffer_write_string(buffer, "0123456789abcdefg");

    auto x = reader.Read();
    assert(!x.IsNull());
    assert(x.size == 17);

    reader.Consume(x.size);

    pool_trash(pool);
    pool_unref(pool);
    pool_commit();
}

/** test growing_buffer_reader_skip() */
static void
test_skip(struct pool *pool)
{
    pool = pool_new_linear(pool, "test", 8192);
    GrowingBuffer *buffer = growing_buffer_new(pool, 3);
    GrowingBufferReader reader(*buffer);

    growing_buffer_write_string(buffer, "0123");
    growing_buffer_write_string(buffer, "4567");
    growing_buffer_write_string(buffer, "89ab");
    growing_buffer_write_string(buffer, "cdef");

    reader.Skip(6);

    auto x = reader.Read();
    assert(!x.IsNull());
    assert(x.size == 2);
    reader.Consume(1);

    reader.Skip(5);

    x = reader.Read();
    assert(!x.IsNull());
    assert(x.size == 4);
    reader.Consume(4);

    x = reader.Read();
    assert(x.IsNull());

    pool_trash(pool);
    pool_unref(pool);
    pool_commit();
}

/** test reading the head while appending to the tail */
static void
test_concurrent_rw(struct pool *pool)
{
    pool = pool_new_linear(pool, "test", 8192);
    GrowingBuffer *buffer = growing_buffer_new(pool, 3);
    GrowingBufferReader reader(*buffer);

    growing_buffer_write_string(buffer, "0123");
    growing_buffer_write_string(buffer, "4567");
    growing_buffer_write_string(buffer, "89ab");
    assert(reader.Available() == 12);

    reader.Skip(12);
    assert(reader.IsEOF());
    assert(reader.Available() == 0);

    growing_buffer_write_string(buffer, "cdef");
    reader.Update();

    assert(!reader.IsEOF());
    assert(reader.Available() == 4);

    auto x = reader.Read();
    assert(!x.IsNull());
    assert(x.size == 4);

    pool_trash(pool);
    pool_unref(pool);
    pool_commit();
}

/** abort without handler */
static void
test_abort_without_handler(struct pool *pool)
{
    Istream *istream;

    pool = pool_new_linear(pool, "test", 8192);

    istream = create_test(pool);
    istream->CloseUnused();

    pool_trash(pool);
    pool_unref(pool);
    pool_commit();
}

/** abort with handler */
static void
test_abort_with_handler(struct pool *pool)
{
    Context ctx(*pool);
    Istream *istream;

    ctx.pool = pool_new_linear(pool, "test", 8192);

    istream = create_test(ctx.pool);
    istream->SetHandler(ctx);

    istream_free(&istream);
    pool_unref(ctx.pool);

    assert(!ctx.abort);

    pool_commit();
}

/** abort in handler */
static void
test_abort_in_handler(struct pool *pool)
{
    Context ctx(*pool_new_linear(pool, "test", 8192));

    ctx.abort_istream = create_test(ctx.pool);
    ctx.abort_istream->SetHandler(ctx);

    while (!ctx.eof && !ctx.abort && !ctx.closed) {
        istream_read_expect(&ctx, ctx.abort_istream);
        event_loop(EVLOOP_ONCE|EVLOOP_NONBLOCK);
    }

    assert(ctx.abort_istream == nullptr);
    assert(!ctx.abort);
    assert(ctx.closed);

    pool_commit();
}

/*
 * main
 *
 */

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

    direct_global_init();
    EventBase event_base;

    /* run test suite */

    test_normal(RootPool());
    test_empty(RootPool());
    test_first_empty(RootPool());
    test_skip(RootPool());
    test_concurrent_rw(RootPool());
    test_abort_without_handler(RootPool());
    test_abort_with_handler(RootPool());
    test_abort_in_handler(RootPool());
}
<commit_msg>test/t_growing_buffer: use class IstreamPointer<commit_after>#include "RootPool.hxx"
#include "growing_buffer.hxx"
#include "direct.hxx"
#include "istream_gb.hxx"
#include "istream/istream.hxx"
#include "istream/Pointer.hxx"
#include "event/Base.hxx"
#include "util/ConstBuffer.hxx"

#include <glib.h>

#include <stdio.h>

struct Context final : IstreamHandler {
    struct pool *pool;
    bool got_data = false, eof = false, abort = false, closed = false;
    IstreamPointer abort_istream;

    explicit Context(struct pool &_pool)
        :pool(&_pool), abort_istream(nullptr) {}

    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    void OnEof() override;
    void OnError(GError *error) override;
};

/*
 * istream handler
 *
 */

size_t
Context::OnData(gcc_unused const void *data, size_t length)
{
    got_data = true;

    if (abort_istream.IsDefined()) {
        closed = true;
        abort_istream.ClearAndClose();
        pool_unref(pool);
        return 0;
    }

    return length;
}

void
Context::OnEof()
{
    eof = true;

    pool_unref(pool);
}

void
Context::OnError(GError *error)
{
    g_error_free(error);

    abort = true;

    pool_unref(pool);
}

/*
 * utils
 *
 */

static int
istream_read_event(IstreamPointer &istream)
{
    istream.Read();
    return event_loop(EVLOOP_ONCE|EVLOOP_NONBLOCK);
}

static void
istream_read_expect(Context *ctx, IstreamPointer &istream)
{
    int ret;

    assert(!ctx->eof);

    ctx->got_data = false;

    ret = istream_read_event(istream);
    assert(ctx->eof || ctx->got_data || ret == 0);

    /* give istream_later another chance to breathe */
    event_loop(EVLOOP_ONCE|EVLOOP_NONBLOCK);
}

static void
run_istream_ctx(Context *ctx, struct pool *pool, Istream *_istream)
{
    gcc_unused off_t a1 = _istream->GetAvailable(false);
    gcc_unused off_t a2 = _istream->GetAvailable(true);

    IstreamPointer istream(*_istream, *ctx);

#ifndef NO_GOT_DATA_ASSERT
    while (!ctx->eof)
        istream_read_expect(ctx, istream);
#else
    for (int i = 0; i < 1000 && !ctx->eof; ++i)
           istream_read_event(istream);
#endif

    if (!ctx->eof) {
        pool_trash(pool);
        pool_unref(pool);
    }

    pool_commit();
}

static void
run_istream(struct pool *pool, Istream *istream)
{
    Context ctx(*pool);
    run_istream_ctx(&ctx, pool, istream);
}

static Istream *
create_test(struct pool *pool)
{
    GrowingBuffer *gb = growing_buffer_new(pool, 64);
    growing_buffer_write_string(gb, "foo");
    return istream_gb_new(*pool, *gb);
}

static Istream *
create_empty(struct pool *pool)
{
    GrowingBuffer *gb = growing_buffer_new(pool, 64);
    return istream_gb_new(*pool, *gb);
}

/*
 * tests
 *
 */

/** normal run */
static void
test_normal(struct pool *pool)
{
    Istream *istream;

    pool = pool_new_linear(pool, "test", 8192);
    istream = create_test(pool);

    run_istream(pool, istream);
}

/** empty input */
static void
test_empty(struct pool *pool)
{
    Istream *istream;

    pool = pool_new_linear(pool, "test", 8192);
    istream = create_empty(pool);

    run_istream(pool, istream);
}

/** first buffer is too small, empty */
static void
test_first_empty(struct pool *pool)
{
    pool = pool_new_linear(pool, "test", 8192);
    GrowingBuffer *buffer = growing_buffer_new(pool, 16);
    GrowingBufferReader reader(*buffer);

    growing_buffer_write_string(buffer, "0123456789abcdefg");

    auto x = reader.Read();
    assert(!x.IsNull());
    assert(x.size == 17);

    reader.Consume(x.size);

    pool_trash(pool);
    pool_unref(pool);
    pool_commit();
}

/** test growing_buffer_reader_skip() */
static void
test_skip(struct pool *pool)
{
    pool = pool_new_linear(pool, "test", 8192);
    GrowingBuffer *buffer = growing_buffer_new(pool, 3);
    GrowingBufferReader reader(*buffer);

    growing_buffer_write_string(buffer, "0123");
    growing_buffer_write_string(buffer, "4567");
    growing_buffer_write_string(buffer, "89ab");
    growing_buffer_write_string(buffer, "cdef");

    reader.Skip(6);

    auto x = reader.Read();
    assert(!x.IsNull());
    assert(x.size == 2);
    reader.Consume(1);

    reader.Skip(5);

    x = reader.Read();
    assert(!x.IsNull());
    assert(x.size == 4);
    reader.Consume(4);

    x = reader.Read();
    assert(x.IsNull());

    pool_trash(pool);
    pool_unref(pool);
    pool_commit();
}

/** test reading the head while appending to the tail */
static void
test_concurrent_rw(struct pool *pool)
{
    pool = pool_new_linear(pool, "test", 8192);
    GrowingBuffer *buffer = growing_buffer_new(pool, 3);
    GrowingBufferReader reader(*buffer);

    growing_buffer_write_string(buffer, "0123");
    growing_buffer_write_string(buffer, "4567");
    growing_buffer_write_string(buffer, "89ab");
    assert(reader.Available() == 12);

    reader.Skip(12);
    assert(reader.IsEOF());
    assert(reader.Available() == 0);

    growing_buffer_write_string(buffer, "cdef");
    reader.Update();

    assert(!reader.IsEOF());
    assert(reader.Available() == 4);

    auto x = reader.Read();
    assert(!x.IsNull());
    assert(x.size == 4);

    pool_trash(pool);
    pool_unref(pool);
    pool_commit();
}

/** abort without handler */
static void
test_abort_without_handler(struct pool *pool)
{
    Istream *istream;

    pool = pool_new_linear(pool, "test", 8192);

    istream = create_test(pool);
    istream->CloseUnused();

    pool_trash(pool);
    pool_unref(pool);
    pool_commit();
}

/** abort with handler */
static void
test_abort_with_handler(struct pool *pool)
{
    Context ctx(*pool);
    Istream *istream;

    ctx.pool = pool_new_linear(pool, "test", 8192);

    istream = create_test(ctx.pool);
    istream->SetHandler(ctx);

    istream_free(&istream);
    pool_unref(ctx.pool);

    assert(!ctx.abort);

    pool_commit();
}

/** abort in handler */
static void
test_abort_in_handler(struct pool *pool)
{
    Context ctx(*pool_new_linear(pool, "test", 8192));

    ctx.abort_istream.Set(*create_test(ctx.pool), ctx);

    while (!ctx.eof && !ctx.abort && !ctx.closed) {
        istream_read_expect(&ctx, ctx.abort_istream);
        event_loop(EVLOOP_ONCE|EVLOOP_NONBLOCK);
    }

    assert(!ctx.abort_istream.IsDefined());
    assert(!ctx.abort);
    assert(ctx.closed);

    pool_commit();
}

/*
 * main
 *
 */

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

    direct_global_init();
    EventBase event_base;

    /* run test suite */

    test_normal(RootPool());
    test_empty(RootPool());
    test_first_empty(RootPool());
    test_skip(RootPool());
    test_concurrent_rw(RootPool());
    test_abort_without_handler(RootPool());
    test_abort_with_handler(RootPool());
    test_abort_in_handler(RootPool());
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "profileinformation.h"

#include "devicesupport/desktopdevice.h"
#include "devicesupport/devicemanager.h"
#include "projectexplorerconstants.h"
#include "profile.h"
#include "profileinformationconfigwidget.h"
#include "toolchain.h"
#include "toolchainmanager.h"

#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/abi.h>
#include <utils/pathchooser.h>

#include <QComboBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>

namespace ProjectExplorer {

// --------------------------------------------------------------------------
// SysRootInformation:
// --------------------------------------------------------------------------

static const char SYSROOT_INFORMATION[] = "PE.Profile.SysRoot";

SysRootProfileInformation::SysRootProfileInformation()
{
    setObjectName(QLatin1String("SysRootInformation"));
}

Core::Id SysRootProfileInformation::dataId() const
{
    static const Core::Id id(SYSROOT_INFORMATION);
    return id;
}

unsigned int SysRootProfileInformation::priority() const
{
    return 32000;
}

QVariant SysRootProfileInformation::defaultValue(Profile *p) const
{
    Q_UNUSED(p)
    return QString();
}

QList<Task> SysRootProfileInformation::validate(Profile *p) const
{
    QList<Task> result;
    const Utils::FileName dir = SysRootProfileInformation::sysRoot(p);
    if (!dir.toFileInfo().isDir() && SysRootProfileInformation::hasSysRoot(p))
        result << Task(Task::Error, QObject::tr("Sys Root \"%1\" is not a directory.").arg(dir.toUserOutput()),
                       Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
    return result;
}

ProfileConfigWidget *SysRootProfileInformation::createConfigWidget(Profile *p) const
{
    Q_ASSERT(p);
    return new Internal::SysRootInformationConfigWidget(p);
}

ProfileInformation::ItemList SysRootProfileInformation::toUserOutput(Profile *p) const
{
    return ItemList() << qMakePair(tr("Sys Root"), sysRoot(p).toUserOutput());
}

bool SysRootProfileInformation::hasSysRoot(const Profile *p)
{
    return !p->value(Core::Id(SYSROOT_INFORMATION)).isNull();
}

Utils::FileName SysRootProfileInformation::sysRoot(const Profile *p)
{
    if (!p)
        return Utils::FileName();
    return Utils::FileName::fromString(p->value(Core::Id(SYSROOT_INFORMATION)).toString());
}

void SysRootProfileInformation::setSysRoot(Profile *p, const Utils::FileName &v)
{
    p->setValue(Core::Id(SYSROOT_INFORMATION), v.toString());
}

// --------------------------------------------------------------------------
// ToolChainInformation:
// --------------------------------------------------------------------------

static const char TOOLCHAIN_INFORMATION[] = "PE.Profile.ToolChain";

ToolChainProfileInformation::ToolChainProfileInformation()
{
    setObjectName(QLatin1String("ToolChainInformation"));
    connect(ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
            this, SIGNAL(validationNeeded()));
    connect(ToolChainManager::instance(), SIGNAL(toolChainUpdated(ProjectExplorer::ToolChain*)),
            this, SIGNAL(validationNeeded()));
}

Core::Id ToolChainProfileInformation::dataId() const
{
    static const Core::Id id(TOOLCHAIN_INFORMATION);
    return id;
}

unsigned int ToolChainProfileInformation::priority() const
{
    return 30000;
}

QVariant ToolChainProfileInformation::defaultValue(Profile *p) const
{
    Q_UNUSED(p);
    QList<ToolChain *> tcList = ToolChainManager::instance()->toolChains();
    if (tcList.isEmpty())
        return QString();

    ProjectExplorer::Abi abi = ProjectExplorer::Abi::hostAbi();

    foreach (ToolChain *tc, tcList) {
        if (tc->targetAbi() == abi)
            return tc->id();
    }

    return tcList.at(0)->id();
}

QList<Task> ToolChainProfileInformation::validate(Profile *p) const
{
    QList<Task> result;
    if (!toolChain(p)) {
        setToolChain(p, 0); // make sure to clear out no longer known tool chains
        result << Task(Task::Error, QObject::tr("No tool chain set up."),
                       Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
    }
    return result;
}

ProfileConfigWidget *ToolChainProfileInformation::createConfigWidget(Profile *p) const
{
    Q_ASSERT(p);
    return new Internal::ToolChainInformationConfigWidget(p);
}

ProfileInformation::ItemList ToolChainProfileInformation::toUserOutput(Profile *p) const
{
    ToolChain *tc = toolChain(p);
    return ItemList() << qMakePair(tr("Tool chain"), tc ? tc->displayName() : tr("None"));
}

void ToolChainProfileInformation::addToEnvironment(const Profile *p, Utils::Environment &env) const
{
    ToolChain *tc = toolChain(p);
    if (tc)
        tc->addToEnvironment(env);
}

ToolChain *ToolChainProfileInformation::toolChain(const Profile *p)
{
    if (!p)
        return 0;
    const QString id = p->value(Core::Id(TOOLCHAIN_INFORMATION)).toString();
    return ToolChainManager::instance()->findToolChain(id);
}

void ToolChainProfileInformation::setToolChain(Profile *p, ToolChain *tc)
{
    p->setValue(Core::Id(TOOLCHAIN_INFORMATION), tc ? tc->id() : QString());
}

// --------------------------------------------------------------------------
// DeviceTypeInformation:
// --------------------------------------------------------------------------

static const char DEVICETYPE_INFORMATION[] = "PE.Profile.DeviceType";

DeviceTypeProfileInformation::DeviceTypeProfileInformation()
{
    setObjectName(QLatin1String("DeviceTypeInformation"));
}

Core::Id DeviceTypeProfileInformation::dataId() const
{
    static const Core::Id id(DEVICETYPE_INFORMATION);
    return id;
}

unsigned int DeviceTypeProfileInformation::priority() const
{
    return 33000;
}

QVariant DeviceTypeProfileInformation::defaultValue(Profile *p) const
{
    Q_UNUSED(p);
    return QByteArray(Constants::DESKTOP_DEVICE_TYPE);
}

QList<Task> DeviceTypeProfileInformation::validate(Profile *p) const
{
    IDevice::ConstPtr dev = DeviceProfileInformation::device(p);
    QList<Task> result;
    if (!dev.isNull() && dev->type() != DeviceTypeProfileInformation::deviceTypeId(p))
        result.append(Task(Task::Error, QObject::tr("Device does not match device type."),
                           Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)));
    return result;
}

ProfileConfigWidget *DeviceTypeProfileInformation::createConfigWidget(Profile *p) const
{
    Q_ASSERT(p);
    return new Internal::DeviceTypeInformationConfigWidget(p);
}

ProfileInformation::ItemList DeviceTypeProfileInformation::toUserOutput(Profile *p) const
{
    Core::Id type = deviceTypeId(p);
    QString typeDisplayName = tr("Unknown device type");
    if (type.isValid()) {
        QList<IDeviceFactory *> factories
                = ExtensionSystem::PluginManager::instance()->getObjects<IDeviceFactory>();
        foreach (IDeviceFactory *factory, factories) {
            if (factory->availableCreationIds().contains(type)) {
                typeDisplayName = factory->displayNameForId(type);
                break;
            }
        }
    }
    return ItemList() << qMakePair(tr("Device type"), typeDisplayName);
}

const Core::Id DeviceTypeProfileInformation::deviceTypeId(const Profile *p)
{
    if (!p)
        return Core::Id();
    return Core::Id(p->value(Core::Id(DEVICETYPE_INFORMATION)).toByteArray().constData());
}

void DeviceTypeProfileInformation::setDeviceTypeId(Profile *p, Core::Id type)
{
    p->setValue(Core::Id(DEVICETYPE_INFORMATION), type.name());
}

// --------------------------------------------------------------------------
// DeviceInformation:
// --------------------------------------------------------------------------

static const char DEVICE_INFORMATION[] = "PE.Profile.Device";

DeviceProfileInformation::DeviceProfileInformation()
{
    setObjectName(QLatin1String("DeviceInformation"));
    connect(DeviceManager::instance(), SIGNAL(deviceRemoved(Core::Id)),
            this, SIGNAL(validationNeeded()));
    connect(DeviceManager::instance(), SIGNAL(deviceUpdated(Core::Id)),
            this, SIGNAL(validationNeeded()));
}

Core::Id DeviceProfileInformation::dataId() const
{
    static const Core::Id id(DEVICE_INFORMATION);
    return id;
}

unsigned int DeviceProfileInformation::priority() const
{
    return 32000;
}

QVariant DeviceProfileInformation::defaultValue(Profile *p) const
{
    Q_UNUSED(p);
    return QByteArray(Constants::DESKTOP_DEVICE_ID);
}

QList<Task> DeviceProfileInformation::validate(Profile *p) const
{
    Q_UNUSED(p);
    QList<Task> result;
    return result;
}

ProfileConfigWidget *DeviceProfileInformation::createConfigWidget(Profile *p) const
{
    Q_ASSERT(p);
    return new Internal::DeviceInformationConfigWidget(p);
}

ProfileInformation::ItemList DeviceProfileInformation::toUserOutput(Profile *p) const
{
    IDevice::ConstPtr dev = device(p);
    return ItemList() << qMakePair(tr("Device"), dev.isNull() ? tr("Unconfigured") : dev->displayName());
}

IDevice::ConstPtr DeviceProfileInformation::device(const Profile *p)
{
    DeviceManager *dm = DeviceManager::instance();
    return dm ? dm->find(deviceId(p)) : IDevice::ConstPtr();
}

Core::Id DeviceProfileInformation::deviceId(const Profile *p)
{
    if (p) {
        QByteArray idname = p->value(Core::Id(DEVICE_INFORMATION)).toByteArray();
        return idname.isEmpty() ? IDevice::invalidId() : Core::Id(idname.constData());
    }
    return IDevice::invalidId();
}

void DeviceProfileInformation::setDevice(Profile *p, IDevice::ConstPtr dev)
{
    setDeviceId(p, dev ? dev->id() : IDevice::invalidId());
}

void DeviceProfileInformation::setDeviceId(Profile *p, const Core::Id id)
{
    p->setValue(Core::Id(DEVICE_INFORMATION), id.name());
}

} // namespace ProjectExplorer
<commit_msg>SysRoot: Do not treat "" as invalid sysroot<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "profileinformation.h"

#include "devicesupport/desktopdevice.h"
#include "devicesupport/devicemanager.h"
#include "projectexplorerconstants.h"
#include "profile.h"
#include "profileinformationconfigwidget.h"
#include "toolchain.h"
#include "toolchainmanager.h"

#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/abi.h>
#include <utils/pathchooser.h>

#include <QComboBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>

namespace ProjectExplorer {

// --------------------------------------------------------------------------
// SysRootInformation:
// --------------------------------------------------------------------------

static const char SYSROOT_INFORMATION[] = "PE.Profile.SysRoot";

SysRootProfileInformation::SysRootProfileInformation()
{
    setObjectName(QLatin1String("SysRootInformation"));
}

Core::Id SysRootProfileInformation::dataId() const
{
    static const Core::Id id(SYSROOT_INFORMATION);
    return id;
}

unsigned int SysRootProfileInformation::priority() const
{
    return 32000;
}

QVariant SysRootProfileInformation::defaultValue(Profile *p) const
{
    Q_UNUSED(p)
    return QString();
}

QList<Task> SysRootProfileInformation::validate(Profile *p) const
{
    QList<Task> result;
    const Utils::FileName dir = SysRootProfileInformation::sysRoot(p);
    if (!dir.toFileInfo().isDir() && SysRootProfileInformation::hasSysRoot(p))
        result << Task(Task::Error, QObject::tr("Sys Root \"%1\" is not a directory.").arg(dir.toUserOutput()),
                       Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
    return result;
}

ProfileConfigWidget *SysRootProfileInformation::createConfigWidget(Profile *p) const
{
    Q_ASSERT(p);
    return new Internal::SysRootInformationConfigWidget(p);
}

ProfileInformation::ItemList SysRootProfileInformation::toUserOutput(Profile *p) const
{
    return ItemList() << qMakePair(tr("Sys Root"), sysRoot(p).toUserOutput());
}

bool SysRootProfileInformation::hasSysRoot(const Profile *p)
{
    return !p->value(Core::Id(SYSROOT_INFORMATION)).toString().isEmpty();
}

Utils::FileName SysRootProfileInformation::sysRoot(const Profile *p)
{
    if (!p)
        return Utils::FileName();
    return Utils::FileName::fromString(p->value(Core::Id(SYSROOT_INFORMATION)).toString());
}

void SysRootProfileInformation::setSysRoot(Profile *p, const Utils::FileName &v)
{
    p->setValue(Core::Id(SYSROOT_INFORMATION), v.toString());
}

// --------------------------------------------------------------------------
// ToolChainInformation:
// --------------------------------------------------------------------------

static const char TOOLCHAIN_INFORMATION[] = "PE.Profile.ToolChain";

ToolChainProfileInformation::ToolChainProfileInformation()
{
    setObjectName(QLatin1String("ToolChainInformation"));
    connect(ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
            this, SIGNAL(validationNeeded()));
    connect(ToolChainManager::instance(), SIGNAL(toolChainUpdated(ProjectExplorer::ToolChain*)),
            this, SIGNAL(validationNeeded()));
}

Core::Id ToolChainProfileInformation::dataId() const
{
    static const Core::Id id(TOOLCHAIN_INFORMATION);
    return id;
}

unsigned int ToolChainProfileInformation::priority() const
{
    return 30000;
}

QVariant ToolChainProfileInformation::defaultValue(Profile *p) const
{
    Q_UNUSED(p);
    QList<ToolChain *> tcList = ToolChainManager::instance()->toolChains();
    if (tcList.isEmpty())
        return QString();

    ProjectExplorer::Abi abi = ProjectExplorer::Abi::hostAbi();

    foreach (ToolChain *tc, tcList) {
        if (tc->targetAbi() == abi)
            return tc->id();
    }

    return tcList.at(0)->id();
}

QList<Task> ToolChainProfileInformation::validate(Profile *p) const
{
    QList<Task> result;
    if (!toolChain(p)) {
        setToolChain(p, 0); // make sure to clear out no longer known tool chains
        result << Task(Task::Error, QObject::tr("No tool chain set up."),
                       Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
    }
    return result;
}

ProfileConfigWidget *ToolChainProfileInformation::createConfigWidget(Profile *p) const
{
    Q_ASSERT(p);
    return new Internal::ToolChainInformationConfigWidget(p);
}

ProfileInformation::ItemList ToolChainProfileInformation::toUserOutput(Profile *p) const
{
    ToolChain *tc = toolChain(p);
    return ItemList() << qMakePair(tr("Tool chain"), tc ? tc->displayName() : tr("None"));
}

void ToolChainProfileInformation::addToEnvironment(const Profile *p, Utils::Environment &env) const
{
    ToolChain *tc = toolChain(p);
    if (tc)
        tc->addToEnvironment(env);
}

ToolChain *ToolChainProfileInformation::toolChain(const Profile *p)
{
    if (!p)
        return 0;
    const QString id = p->value(Core::Id(TOOLCHAIN_INFORMATION)).toString();
    return ToolChainManager::instance()->findToolChain(id);
}

void ToolChainProfileInformation::setToolChain(Profile *p, ToolChain *tc)
{
    p->setValue(Core::Id(TOOLCHAIN_INFORMATION), tc ? tc->id() : QString());
}

// --------------------------------------------------------------------------
// DeviceTypeInformation:
// --------------------------------------------------------------------------

static const char DEVICETYPE_INFORMATION[] = "PE.Profile.DeviceType";

DeviceTypeProfileInformation::DeviceTypeProfileInformation()
{
    setObjectName(QLatin1String("DeviceTypeInformation"));
}

Core::Id DeviceTypeProfileInformation::dataId() const
{
    static const Core::Id id(DEVICETYPE_INFORMATION);
    return id;
}

unsigned int DeviceTypeProfileInformation::priority() const
{
    return 33000;
}

QVariant DeviceTypeProfileInformation::defaultValue(Profile *p) const
{
    Q_UNUSED(p);
    return QByteArray(Constants::DESKTOP_DEVICE_TYPE);
}

QList<Task> DeviceTypeProfileInformation::validate(Profile *p) const
{
    IDevice::ConstPtr dev = DeviceProfileInformation::device(p);
    QList<Task> result;
    if (!dev.isNull() && dev->type() != DeviceTypeProfileInformation::deviceTypeId(p))
        result.append(Task(Task::Error, QObject::tr("Device does not match device type."),
                           Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)));
    return result;
}

ProfileConfigWidget *DeviceTypeProfileInformation::createConfigWidget(Profile *p) const
{
    Q_ASSERT(p);
    return new Internal::DeviceTypeInformationConfigWidget(p);
}

ProfileInformation::ItemList DeviceTypeProfileInformation::toUserOutput(Profile *p) const
{
    Core::Id type = deviceTypeId(p);
    QString typeDisplayName = tr("Unknown device type");
    if (type.isValid()) {
        QList<IDeviceFactory *> factories
                = ExtensionSystem::PluginManager::instance()->getObjects<IDeviceFactory>();
        foreach (IDeviceFactory *factory, factories) {
            if (factory->availableCreationIds().contains(type)) {
                typeDisplayName = factory->displayNameForId(type);
                break;
            }
        }
    }
    return ItemList() << qMakePair(tr("Device type"), typeDisplayName);
}

const Core::Id DeviceTypeProfileInformation::deviceTypeId(const Profile *p)
{
    if (!p)
        return Core::Id();
    return Core::Id(p->value(Core::Id(DEVICETYPE_INFORMATION)).toByteArray().constData());
}

void DeviceTypeProfileInformation::setDeviceTypeId(Profile *p, Core::Id type)
{
    p->setValue(Core::Id(DEVICETYPE_INFORMATION), type.name());
}

// --------------------------------------------------------------------------
// DeviceInformation:
// --------------------------------------------------------------------------

static const char DEVICE_INFORMATION[] = "PE.Profile.Device";

DeviceProfileInformation::DeviceProfileInformation()
{
    setObjectName(QLatin1String("DeviceInformation"));
    connect(DeviceManager::instance(), SIGNAL(deviceRemoved(Core::Id)),
            this, SIGNAL(validationNeeded()));
    connect(DeviceManager::instance(), SIGNAL(deviceUpdated(Core::Id)),
            this, SIGNAL(validationNeeded()));
}

Core::Id DeviceProfileInformation::dataId() const
{
    static const Core::Id id(DEVICE_INFORMATION);
    return id;
}

unsigned int DeviceProfileInformation::priority() const
{
    return 32000;
}

QVariant DeviceProfileInformation::defaultValue(Profile *p) const
{
    Q_UNUSED(p);
    return QByteArray(Constants::DESKTOP_DEVICE_ID);
}

QList<Task> DeviceProfileInformation::validate(Profile *p) const
{
    Q_UNUSED(p);
    QList<Task> result;
    return result;
}

ProfileConfigWidget *DeviceProfileInformation::createConfigWidget(Profile *p) const
{
    Q_ASSERT(p);
    return new Internal::DeviceInformationConfigWidget(p);
}

ProfileInformation::ItemList DeviceProfileInformation::toUserOutput(Profile *p) const
{
    IDevice::ConstPtr dev = device(p);
    return ItemList() << qMakePair(tr("Device"), dev.isNull() ? tr("Unconfigured") : dev->displayName());
}

IDevice::ConstPtr DeviceProfileInformation::device(const Profile *p)
{
    DeviceManager *dm = DeviceManager::instance();
    return dm ? dm->find(deviceId(p)) : IDevice::ConstPtr();
}

Core::Id DeviceProfileInformation::deviceId(const Profile *p)
{
    if (p) {
        QByteArray idname = p->value(Core::Id(DEVICE_INFORMATION)).toByteArray();
        return idname.isEmpty() ? IDevice::invalidId() : Core::Id(idname.constData());
    }
    return IDevice::invalidId();
}

void DeviceProfileInformation::setDevice(Profile *p, IDevice::ConstPtr dev)
{
    setDeviceId(p, dev ? dev->id() : IDevice::invalidId());
}

void DeviceProfileInformation::setDeviceId(Profile *p, const Core::Id id)
{
    p->setValue(Core::Id(DEVICE_INFORMATION), id.name());
}

} // namespace ProjectExplorer
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "qmlprojectplugin.h"
#include "qmlprojectmanager.h"
#include "qmlprojectimportwizard.h"
#include "qmlprojectapplicationwizard.h"
#include "qmlstandaloneappwizard.h"
#include "qmlprojectconstants.h"
#include "qmlproject.h"
#include "qmlprojectrunconfigurationfactory.h"
#include "qmlprojectruncontrol.h"
#include "fileformat/qmlprojectfileformat.h"

#include <extensionsystem/pluginmanager.h>

#include <coreplugin/fileiconprovider.h>
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>

#include <texteditor/texteditoractionhandler.h>

#include <projectexplorer/taskhub.h>

#include <QtCore/QtPlugin>

namespace QmlProjectManager {
namespace Internal {

QmlProjectPlugin::QmlProjectPlugin()
{ }

QmlProjectPlugin::~QmlProjectPlugin()
{
}

bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
{
    using namespace Core;

    ICore *core = ICore::instance();
    Core::MimeDatabase *mimeDB = core->mimeDatabase();

    const QLatin1String mimetypesXml(":qmlproject/QmlProject.mimetypes.xml");

    if (! mimeDB->addMimeTypes(mimetypesXml, errorMessage))
        return false;

    Manager *manager = new Manager;

    addAutoReleasedObject(manager);
    addAutoReleasedObject(new Internal::QmlProjectRunConfigurationFactory);
    addAutoReleasedObject(new Internal::QmlRunControlFactory);
    addAutoReleasedObject(new QmlStandaloneAppWizard(QmlStandaloneAppWizard::NewQmlFile));
    addAutoReleasedObject(new QmlStandaloneAppWizard(QmlStandaloneAppWizard::ImportQmlFile));
    addAutoReleasedObject(new QmlProjectApplicationWizard);
    addAutoReleasedObject(new QmlProjectImportWizard);

    QmlProjectFileFormat::registerDeclarativeTypes();

    Core::FileIconProvider *iconProvider = Core::FileIconProvider::instance();
    iconProvider->registerIconOverlayForSuffix(QIcon(QLatin1String(":/qmlproject/images/qmlproject.png")), "qmlproject");
    return true;
}

void QmlProjectPlugin::extensionsInitialized()
{
}

} // namespace Internal
} // namespace QmlProjectManager

Q_EXPORT_PLUGIN(QmlProjectManager::Internal::QmlProjectPlugin)
<commit_msg>Fix of a (harmless) typo<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "qmlprojectplugin.h"
#include "qmlprojectmanager.h"
#include "qmlprojectimportwizard.h"
#include "qmlprojectapplicationwizard.h"
#include "qmlstandaloneappwizard.h"
#include "qmlprojectconstants.h"
#include "qmlproject.h"
#include "qmlprojectrunconfigurationfactory.h"
#include "qmlprojectruncontrol.h"
#include "fileformat/qmlprojectfileformat.h"

#include <extensionsystem/pluginmanager.h>

#include <coreplugin/fileiconprovider.h>
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>

#include <texteditor/texteditoractionhandler.h>

#include <projectexplorer/taskhub.h>

#include <QtCore/QtPlugin>

namespace QmlProjectManager {
namespace Internal {

QmlProjectPlugin::QmlProjectPlugin()
{ }

QmlProjectPlugin::~QmlProjectPlugin()
{
}

bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
{
    using namespace Core;

    ICore *core = ICore::instance();
    Core::MimeDatabase *mimeDB = core->mimeDatabase();

    const QLatin1String mimetypesXml(":/qmlproject/QmlProject.mimetypes.xml");

    if (! mimeDB->addMimeTypes(mimetypesXml, errorMessage))
        return false;

    Manager *manager = new Manager;

    addAutoReleasedObject(manager);
    addAutoReleasedObject(new Internal::QmlProjectRunConfigurationFactory);
    addAutoReleasedObject(new Internal::QmlRunControlFactory);
    addAutoReleasedObject(new QmlStandaloneAppWizard(QmlStandaloneAppWizard::NewQmlFile));
    addAutoReleasedObject(new QmlStandaloneAppWizard(QmlStandaloneAppWizard::ImportQmlFile));
    addAutoReleasedObject(new QmlProjectApplicationWizard);
    addAutoReleasedObject(new QmlProjectImportWizard);

    QmlProjectFileFormat::registerDeclarativeTypes();

    Core::FileIconProvider *iconProvider = Core::FileIconProvider::instance();
    iconProvider->registerIconOverlayForSuffix(QIcon(QLatin1String(":/qmlproject/images/qmlproject.png")), "qmlproject");
    return true;
}

void QmlProjectPlugin::extensionsInitialized()
{
}

} // namespace Internal
} // namespace QmlProjectManager

Q_EXPORT_PLUGIN(QmlProjectManager::Internal::QmlProjectPlugin)
<|endoftext|>


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

#include "RobotDevastation.hpp"

bool rd::RobotDevastation::configure(yarp::os::ResourceFinder &rf)
{
    //-- Show help
    //printf("--------------------------------------------------------------\n");
    if (rf.check("help")) {
        printf("RobotDevastation options:\n");
        printf("\t--help (this help)\t--from [file.ini]\t--context [path]\n");
        printf("\t--id integer\n");
        printf("\t--name string\n");
        printf("\t--team integer\n");
        printf("\t--robot string\n");
        // Do not exit: let last layer exit so we get help from the complete chain.
    }
    printf("RobotDevastation using no additional special options.\n");

    //-- Get player data
    //-----------------------------------------------------------------------------
    rdRoot = ::getenv ("RD_ROOT");
    if (rdRoot!=NULL)
    {
        RD_INFO("The RD_ROOT is: %s\n",rdRoot);
    }
    else
    {
        RD_WARNING("No RD_ROOT environment variable!\n");
        rdRoot="../..";  //-- Allow to run from build/bin
    }

    if( ! rf.check("id") )
    {
        RD_ERROR("No id!\n");
        return false;
    }
    RD_INFO("id: %d\n",rf.find("id").asInt());

    if( ! rf.check("name") )
    {
        RD_ERROR("No name!\n");
        return false;
    }
    RD_INFO("name: %s\n",rf.find("name").asString().c_str());

    if( ! rf.check("team") )
    {
        RD_ERROR("No team!\n");
        return false;
    }
    RD_INFO("team: %d\n",rf.find("team").asInt());

    if( ! rf.check("robot") )
    {
        RD_ERROR("No robot!\n");
        return false;
    }
    RD_INFO("robot: %s\n",rf.find("robot").asString().c_str());

    //-- Init mentalMap
    mentalMap = RdMentalMap::getMentalMap();
    mentalMap->configure( rf.find("id").asInt() );

    std::vector< RdPlayer > players;
    players.push_back( RdPlayer(rf.find("id").asInt(),std::string(rf.find("name").asString()),100,100,rf.find("team").asInt(),0) );
    mentalMap->updatePlayers(players);

    mentalMap->addWeapon(RdWeapon("Default gun", 10, 5));

    //-- Init input manager
    inputManager = RdInputManager::getInputManager();
    inputManager->addInputEventListener(this);
    if (!inputManager->start() )
    {
        RD_ERROR("Could not init inputManager!\n");
        return false;
    }

    //-- Init sound
    if( ! initSound() )
        return false;

    audioManager->playMusic("bso", -1);

    //-- Init robot
    if( rf.find("robot").asString() == "rd1")
        robotManager = new RdRd1RobotManager(rf.find("id").asInt());
    else if( rf.find("robot").asString() == "ecro")
        robotManager = new RdEcroRobotManager(rf.find("id").asInt());
    else {
        RD_ERROR("Unknown robot type \"%s\"!\n", rf.find("robot").asString().c_str());
        return false;
    }
    if( ! robotManager->connect() ) {
        RD_ERROR("Could not connect to robot id \"%d\" type \"%s\"!\n",rf.find("id").asInt(),rf.find("robot").asString().c_str());
        RD_ERROR("Use syntax: robotDevastation --id %d --robot %s\n",rf.find("id").asInt(),rf.find("robot").asString().c_str());
        return false;
    }

    //-- Init network manager
    networkManager = RdYarpNetworkManager::getNetworkManager();
    networkManager->addNetworkEventListener(mentalMap);
    mentalMap->addMentalMapEventListener((RdYarpNetworkManager *)networkManager);
    networkManager->login(mentalMap->getMyself());

    //-- Init image manager
    RdYarpImageManager::RegisterManager();
    imageManager = RdImageManager::getImageManager(RdYarpImageManager::id);
    //-- Add the image processing listener to the image manager
    imageManager->addImageEventListener(&processorImageEventListener);
    //-- Configure the camera port
    std::ostringstream remoteCameraPortName;  //-- Default looks like "/0/rd1/img:o"
    remoteCameraPortName << "/";
    remoteCameraPortName << rf.find("id").asInt();
    remoteCameraPortName << "/";
    remoteCameraPortName << rf.find("robot").asString();
    remoteCameraPortName << "/img:o";
    imageManager->configure("remote_img_port", remoteCameraPortName.str() );
    std::ostringstream localCameraPortName;  //-- Default should look like "/0/robot/img:i"
    localCameraPortName << "/";
    localCameraPortName << rf.find("id").asInt();
    localCameraPortName << "/robot/img:i";
    imageManager->configure("local_img_port", localCameraPortName.str() ); //-- Name given by me
    if( ! imageManager->start() )
        return false;

    //-- Init output thread
    rateThreadOutput.setRdRoot(rdRoot);
    rateThreadOutput.init(rf);

    return true;
}

bool rd::RobotDevastation::onKeyUp(rd::RdKey k)
{
if (k.isPrintable() )
    {
        RD_SUCCESS( "Key \"%c\" was pressed!\n", k.getChar() );

        if ( k.getChar() == 'w')
        {
            robotManager->stopMovement();
        }
        else if ( k.getChar() == 'a')
        {
            robotManager->stopMovement();
        }
        else if ( k.getChar() == 's')
        {
            robotManager->stopMovement();
        }
        else if ( k.getChar() == 'd')
        {
            robotManager->stopMovement();
        }
    }
	return true;
}

bool rd::RobotDevastation::onKeyDown(rd::RdKey k)
{
    if ( k.isControlKey() )
    {
        RD_SUCCESS( "Control key with code %d pressed!\n", k.getValue() );

        if ( k.getValue() == RdKey::KEY_SPACE)
        {
            //-- Do things to shoot
            mentalMap->shoot();
            RD_SUCCESS("Shoot!\n");
        }
        else if ( k.getValue() == RdKey::KEY_ESCAPE)
        {
            RD_SUCCESS("Exit!\n");
            this->interruptModule();
        }
    }
    else if (k.isPrintable() )
    {
        RD_SUCCESS( "Key \"%c\" was pressed!\n", k.getChar() );

        if ( k.getChar() == 'r')
        {
            RD_SUCCESS("Reload!\n");
            mentalMap->reload();
        }
        else if ( k.getChar() == 'q')
        {
            RD_SUCCESS("Exit!\n");
            this->interruptModule();
        }
        else if ( k.getChar() == 'w')
        {
            robotManager->moveForward();
        }
        else if ( k.getChar() == 'a')
        {
            robotManager->turnLeft();
        }
        else if ( k.getChar() == 'd')
        {
            robotManager->turnRight();
        }
        else if ( k.getChar() == 's')
        {
            robotManager->moveBackwards();
        }
    }
	return true;
}

double rd::RobotDevastation::getPeriod()
{
    return 2.0;  // Fixed, in seconds, the slow thread that calls updateModule below
}

bool rd::RobotDevastation::updateModule()
{
    printf("===robotDevastation===\n");
    printf("Number of players: %zd\n",mentalMap->getPlayers().size());
    for(size_t i=0;i<mentalMap->getPlayers().size();i++)
    {
       printf("----------------------\n%s\n",mentalMap->getPlayers().at(i).str().c_str());
    }
    //printf("======================\n");
    return true;
}

bool rd::RobotDevastation::initSound()
{
    std::string rdRootStr(rdRoot);

    audioManager = RdAudioManager::getAudioManager();

    if ( ! audioManager->load(rdRootStr+"/share/sounds/RobotDevastationBSO.mp3", "bso", 0) )
        return false;

    if ( ! audioManager->load(rdRootStr+"/share/sounds/01_milshot.wav", "shoot", 1) )
        return false;

    if ( ! audioManager->load(rdRootStr+"/share/sounds/15_explosion.wav", "explosion", 1) )
        return false;

    if ( ! audioManager->load(rdRootStr+"/share/sounds/03_clip.wav", "noAmmo", 1) )
        return false;

    if ( ! audioManager->load(rdRootStr+"/share/sounds/04_milaction.wav", "reload", 1) )
        return false;

    return true;
}

bool rd::RobotDevastation::interruptModule()
{
    RD_INFO("Closing program...\n");

    rateThreadOutput.stop();

    //-- Detach listeners to avoid segmentation faults
    inputManager->removeInputEventListeners();
    networkManager->removeNetworkEventListeners();
    mentalMap->removeMentalMapEventListeners();
    imageManager->removeImageEventListeners();

    //-- Closing input manager:
    RdInputManager::destroyInputManager();
    inputManager = NULL;

    //-- Closing network system
    networkManager->logout(mentalMap->getMyself());
    RdYarpNetworkManager::destroyNetworkManager();
    networkManager = NULL;

    //-- Closing audio system:
    RdAudioManager::destroyAudioManager();
    audioManager = NULL;

    //-- Closing mental map:
    RdMentalMap::destroyMentalMap();
    mentalMap = NULL;

    //-- Close img related ports:
    imageManager->stop();
    RdImageManager::destroyImageManager();
    imageManager = NULL;

    robotManager->disconnect();

    return true;
}

<commit_msg>add noMusic option (does not cancel out fx)<commit_after>// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

#include "RobotDevastation.hpp"

bool rd::RobotDevastation::configure(yarp::os::ResourceFinder &rf)
{
    //-- Show help
    //printf("--------------------------------------------------------------\n");
    if (rf.check("help")) {
        printf("RobotDevastation options:\n");
        printf("\t--help (this help)\t--from [file.ini]\t--context [path]\n");
        printf("\t--id integer\n");
        printf("\t--name string\n");
        printf("\t--team integer\n");
        printf("\t--robot string\n");
        // Do not exit: let last layer exit so we get help from the complete chain.
    }
    printf("RobotDevastation using no additional special options.\n");

    //-- Get player data
    //-----------------------------------------------------------------------------
    rdRoot = ::getenv ("RD_ROOT");
    if (rdRoot!=NULL)
    {
        RD_INFO("The RD_ROOT is: %s\n",rdRoot);
    }
    else
    {
        RD_WARNING("No RD_ROOT environment variable!\n");
        rdRoot="../..";  //-- Allow to run from build/bin
    }

    if( ! rf.check("id") )
    {
        RD_ERROR("No id!\n");
        return false;
    }
    RD_INFO("id: %d\n",rf.find("id").asInt());

    if( ! rf.check("name") )
    {
        RD_ERROR("No name!\n");
        return false;
    }
    RD_INFO("name: %s\n",rf.find("name").asString().c_str());

    if( ! rf.check("team") )
    {
        RD_ERROR("No team!\n");
        return false;
    }
    RD_INFO("team: %d\n",rf.find("team").asInt());

    if( ! rf.check("robot") )
    {
        RD_ERROR("No robot!\n");
        return false;
    }
    RD_INFO("robot: %s\n",rf.find("robot").asString().c_str());

    //-- Init mentalMap
    mentalMap = RdMentalMap::getMentalMap();
    mentalMap->configure( rf.find("id").asInt() );

    std::vector< RdPlayer > players;
    players.push_back( RdPlayer(rf.find("id").asInt(),std::string(rf.find("name").asString()),100,100,rf.find("team").asInt(),0) );
    mentalMap->updatePlayers(players);

    mentalMap->addWeapon(RdWeapon("Default gun", 10, 5));

    //-- Init input manager
    inputManager = RdInputManager::getInputManager();
    inputManager->addInputEventListener(this);
    if (!inputManager->start() )
    {
        RD_ERROR("Could not init inputManager!\n");
        return false;
    }

    //-- Init sound
    if( ! initSound() )
        return false;

    if( ! rf.check("noMusic") )
        audioManager->playMusic("bso", -1);

    //-- Init robot
    if( rf.find("robot").asString() == "rd1")
        robotManager = new RdRd1RobotManager(rf.find("id").asInt());
    else if( rf.find("robot").asString() == "ecro")
        robotManager = new RdEcroRobotManager(rf.find("id").asInt());
    else {
        RD_ERROR("Unknown robot type \"%s\"!\n", rf.find("robot").asString().c_str());
        return false;
    }
    if( ! robotManager->connect() ) {
        RD_ERROR("Could not connect to robot id \"%d\" type \"%s\"!\n",rf.find("id").asInt(),rf.find("robot").asString().c_str());
        RD_ERROR("Use syntax: robotDevastation --id %d --robot %s\n",rf.find("id").asInt(),rf.find("robot").asString().c_str());
        return false;
    }

    //-- Init network manager
    networkManager = RdYarpNetworkManager::getNetworkManager();
    networkManager->addNetworkEventListener(mentalMap);
    mentalMap->addMentalMapEventListener((RdYarpNetworkManager *)networkManager);
    networkManager->login(mentalMap->getMyself());

    //-- Init image manager
    RdYarpImageManager::RegisterManager();
    imageManager = RdImageManager::getImageManager(RdYarpImageManager::id);
    //-- Add the image processing listener to the image manager
    imageManager->addImageEventListener(&processorImageEventListener);
    //-- Configure the camera port
    std::ostringstream remoteCameraPortName;  //-- Default looks like "/0/rd1/img:o"
    remoteCameraPortName << "/";
    remoteCameraPortName << rf.find("id").asInt();
    remoteCameraPortName << "/";
    remoteCameraPortName << rf.find("robot").asString();
    remoteCameraPortName << "/img:o";
    imageManager->configure("remote_img_port", remoteCameraPortName.str() );
    std::ostringstream localCameraPortName;  //-- Default should look like "/0/robot/img:i"
    localCameraPortName << "/";
    localCameraPortName << rf.find("id").asInt();
    localCameraPortName << "/robot/img:i";
    imageManager->configure("local_img_port", localCameraPortName.str() ); //-- Name given by me
    if( ! imageManager->start() )
        return false;

    //-- Init output thread
    rateThreadOutput.setRdRoot(rdRoot);
    rateThreadOutput.init(rf);

    return true;
}

bool rd::RobotDevastation::onKeyUp(rd::RdKey k)
{
if (k.isPrintable() )
    {
        RD_SUCCESS( "Key \"%c\" was pressed!\n", k.getChar() );

        if ( k.getChar() == 'w')
        {
            robotManager->stopMovement();
        }
        else if ( k.getChar() == 'a')
        {
            robotManager->stopMovement();
        }
        else if ( k.getChar() == 's')
        {
            robotManager->stopMovement();
        }
        else if ( k.getChar() == 'd')
        {
            robotManager->stopMovement();
        }
    }
	return true;
}

bool rd::RobotDevastation::onKeyDown(rd::RdKey k)
{
    if ( k.isControlKey() )
    {
        RD_SUCCESS( "Control key with code %d pressed!\n", k.getValue() );

        if ( k.getValue() == RdKey::KEY_SPACE)
        {
            //-- Do things to shoot
            mentalMap->shoot();
            RD_SUCCESS("Shoot!\n");
        }
        else if ( k.getValue() == RdKey::KEY_ESCAPE)
        {
            RD_SUCCESS("Exit!\n");
            this->interruptModule();
        }
    }
    else if (k.isPrintable() )
    {
        RD_SUCCESS( "Key \"%c\" was pressed!\n", k.getChar() );

        if ( k.getChar() == 'r')
        {
            RD_SUCCESS("Reload!\n");
            mentalMap->reload();
        }
        else if ( k.getChar() == 'q')
        {
            RD_SUCCESS("Exit!\n");
            this->interruptModule();
        }
        else if ( k.getChar() == 'w')
        {
            robotManager->moveForward();
        }
        else if ( k.getChar() == 'a')
        {
            robotManager->turnLeft();
        }
        else if ( k.getChar() == 'd')
        {
            robotManager->turnRight();
        }
        else if ( k.getChar() == 's')
        {
            robotManager->moveBackwards();
        }
    }
	return true;
}

double rd::RobotDevastation::getPeriod()
{
    return 2.0;  // Fixed, in seconds, the slow thread that calls updateModule below
}

bool rd::RobotDevastation::updateModule()
{
    printf("===robotDevastation===\n");
    printf("Number of players: %zd\n",mentalMap->getPlayers().size());
    for(size_t i=0;i<mentalMap->getPlayers().size();i++)
    {
       printf("----------------------\n%s\n",mentalMap->getPlayers().at(i).str().c_str());
    }
    //printf("======================\n");
    return true;
}

bool rd::RobotDevastation::initSound()
{
    std::string rdRootStr(rdRoot);

    audioManager = RdAudioManager::getAudioManager();

    if ( ! audioManager->load(rdRootStr+"/share/sounds/RobotDevastationBSO.mp3", "bso", 0) )
        return false;

    if ( ! audioManager->load(rdRootStr+"/share/sounds/01_milshot.wav", "shoot", 1) )
        return false;

    if ( ! audioManager->load(rdRootStr+"/share/sounds/15_explosion.wav", "explosion", 1) )
        return false;

    if ( ! audioManager->load(rdRootStr+"/share/sounds/03_clip.wav", "noAmmo", 1) )
        return false;

    if ( ! audioManager->load(rdRootStr+"/share/sounds/04_milaction.wav", "reload", 1) )
        return false;

    return true;
}

bool rd::RobotDevastation::interruptModule()
{
    RD_INFO("Closing program...\n");

    rateThreadOutput.stop();

    //-- Detach listeners to avoid segmentation faults
    inputManager->removeInputEventListeners();
    networkManager->removeNetworkEventListeners();
    mentalMap->removeMentalMapEventListeners();
    imageManager->removeImageEventListeners();

    //-- Closing input manager:
    RdInputManager::destroyInputManager();
    inputManager = NULL;

    //-- Closing network system
    networkManager->logout(mentalMap->getMyself());
    RdYarpNetworkManager::destroyNetworkManager();
    networkManager = NULL;

    //-- Closing audio system:
    RdAudioManager::destroyAudioManager();
    audioManager = NULL;

    //-- Closing mental map:
    RdMentalMap::destroyMentalMap();
    mentalMap = NULL;

    //-- Close img related ports:
    imageManager->stop();
    RdImageManager::destroyImageManager();
    imageManager = NULL;

    robotManager->disconnect();

    return true;
}

<|endoftext|>