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

#include "src/core/lib/security/credentials/google_default/google_default_credentials.h"

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>

#include "src/core/lib/support/env.h"
#include "src/core/lib/support/string.h"

char* grpc_get_well_known_google_credentials_file_path_impl(void) {
  char* result = nullptr;
  char* base = gpr_getenv(GRPC_GOOGLE_CREDENTIALS_PATH_ENV_VAR);
  if (base == nullptr) {
    gpr_log(GPR_ERROR, "Could not get " GRPC_GOOGLE_CREDENTIALS_ENV_VAR
                       " environment variable.");
    return nullptr;
  }
  gpr_asprintf(&result, "%s/%s", base, GRPC_GOOGLE_CREDENTIALS_PATH_SUFFIX);
  gpr_free(base);
  return result;
}
<commit_msg>Use the correct env var name<commit_after>/*
 *
 * Copyright 2016 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "src/core/lib/security/credentials/google_default/google_default_credentials.h"

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>

#include "src/core/lib/support/env.h"
#include "src/core/lib/support/string.h"

char* grpc_get_well_known_google_credentials_file_path_impl(void) {
  char* result = nullptr;
  char* base = gpr_getenv(GRPC_GOOGLE_CREDENTIALS_PATH_ENV_VAR);
  if (base == nullptr) {
    gpr_log(GPR_ERROR, "Could not get " GRPC_GOOGLE_CREDENTIALS_PATH_ENV_VAR
                       " environment variable.");
    return nullptr;
  }
  gpr_asprintf(&result, "%s/%s", base, GRPC_GOOGLE_CREDENTIALS_PATH_SUFFIX);
  gpr_free(base);
  return result;
}
<|endoftext|>


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <vector>
#include <string>

#include <Exceptions.hpp>
#include <utils.hpp>

#ifndef TRANSPOSE_HPP
#define TRANSPOSE_HPP

namespace isa {
namespace OpenCL {

// Sequential transpose
template< typename T > void transpose(std::vector< T > &input, std::vector< T > &output);
// OpenCL transpose
std::string * getTransposeOpenCL(const unsigned int nrThreads, const unsigned int M, const unsigned int N, const unsigned int padding, const unsigned int vector, std::string typeName);

// Implementations
template< typename T > void transpose(const unsigned int M, const unsigned int N, const unsigned int padding, std::vector< T > &input, std::vector< T > &output) {
  for ( unsigned int i = 0; i < M; i++ ) {
    for ( unsigned int j = 0; j < N; j++ ) {
      output[(j * isa::utils::pad(M, padding)) + i] = input[(i * isa::utils::pad(N, padding)) + j];
    }
  }
}

std::string * getTransposeOpenCL(const unsigned int nrThreads, const unsigned int M, const unsigned int N, const unsigned int padding, const unsigned int vector, std::string typeName) {
  std::string * code = new std::string();

  // Begin kernel's template
	*code = "__kernel void " + this->name + "(__global const " + typeName + " * const restrict input, __global " + typeName + " * const restrict output) {\n"
	"const unsigned int baseM = get_group_id(0) * " + isa::utils::toString(nrThreads) + ";\n"
	"const unsigned int baseN = get_group_id(1) * " + isa::utils::toString(nrThreads) + ";\n"
	"__local "+ typeName + " tempStorage[" + isa::utils::toString(nrThreads * nrThreads) + "];"
	"\n"
	// Load input
	"for ( unsigned int m = 0; m < " + isa::utils::toString(nrThreads) + "; m++ ) {\n"
	"if ( baseN + get_local_id(0) < " + isa::utils::toString(N) + " ) {\n"
	"tempStorage[(m * " + isa::utils::toString(nrThreads) + ") + get_local_id(0)] = input[((baseM + m) * " + isa::utils::toString(isa::utils::pad(N, padding)) + ") + (baseN + get_local_id(0))];\n"
	"}\n"
	"}\n";
	if ( nrThreads > vector ) {
		*code += "barrier(CLK_LOCAL_MEM_FENCE);\n";
	}
	// Local in-place transpose
	*code += "for ( unsigned int i = 1; i <= " + isa::utils::toString(nrThreads) + " / 2; i++ ) {\n"
	"unsigned int localItem = (get_local_id(0) + i) % " + isa::utils::toString(nrThreads) + ";\n"
	+ typeName + " temp = 0;\n";
	if ( nrThreads == vector ) {
		*code += "if ( (i < "+ isa::utils::toString(nrThreads) + ") || (get_local_id(0) < " + isa::utils::toString(nrThreads) + " / 2) ) {\n";
	} else {
		*code += "if ( (i < "+ isa::utils::toString(nrThreads) + " - " + isa::utils::toString(nrThreads / 2) + ") || (get_local_id(0) < " + isa::utils::toString(nrThreads) + " / 2) ) {\n";
	}
	*code += "temp = tempStorage[(get_local_id(0) * " + isa::utils::toString(nrThreads) + ") + localItem];\n"
	"tempStorage[(get_local_id(0) * " + isa::utils::toString(nrThreads) + ") + localItem] = tempStorage[(localItem * " + isa::utils::toString(nrThreads) + ") + get_local_id(0)];\n"
	"tempStorage[(localItem * " + isa::utils::toString(nrThreads) + ") + get_local_id(0)] = temp;\n"
	"}\n"
	"}\n";
	if ( nrThreads > vector ) {
		*code += "barrier(CLK_LOCAL_MEM_FENCE);\n";
	}
	// Store output
	*code += "for ( unsigned int n = 0; n < " + isa::utils::toString(nrThreads) + "; n++ ) {\n"
	"if ( baseN + n < " + isa::utils::toString(N) + " ) {\n"
	"output[((baseN + n) * " + isa::utils::toString(isa::utils::pad(M, padding)) + ") + (baseM + get_local_id(0))] = tempStorage[(n * " + isa::utils::toString(nrThreads) + ") + get_local_id(0)];"
	"}\n"
	"}\n"
	"}\n";
  // End kernel's template

  return code;
}

} // OpenCl
} // isa

#endif // TRANSPOSE_HPP
<commit_msg>Forgot a "this".<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <vector>
#include <string>

#include <Exceptions.hpp>
#include <utils.hpp>

#ifndef TRANSPOSE_HPP
#define TRANSPOSE_HPP

namespace isa {
namespace OpenCL {

// Sequential transpose
template< typename T > void transpose(std::vector< T > &input, std::vector< T > &output);
// OpenCL transpose
std::string * getTransposeOpenCL(const unsigned int nrThreads, const unsigned int M, const unsigned int N, const unsigned int padding, const unsigned int vector, std::string typeName);

// Implementations
template< typename T > void transpose(const unsigned int M, const unsigned int N, const unsigned int padding, std::vector< T > &input, std::vector< T > &output) {
  for ( unsigned int i = 0; i < M; i++ ) {
    for ( unsigned int j = 0; j < N; j++ ) {
      output[(j * isa::utils::pad(M, padding)) + i] = input[(i * isa::utils::pad(N, padding)) + j];
    }
  }
}

std::string * getTransposeOpenCL(const unsigned int nrThreads, const unsigned int M, const unsigned int N, const unsigned int padding, const unsigned int vector, std::string typeName) {
  std::string * code = new std::string();

  // Begin kernel's template
	*code = "__kernel void transpose(__global const " + typeName + " * const restrict input, __global " + typeName + " * const restrict output) {\n"
	"const unsigned int baseM = get_group_id(0) * " + isa::utils::toString(nrThreads) + ";\n"
	"const unsigned int baseN = get_group_id(1) * " + isa::utils::toString(nrThreads) + ";\n"
	"__local "+ typeName + " tempStorage[" + isa::utils::toString(nrThreads * nrThreads) + "];"
	"\n"
	// Load input
	"for ( unsigned int m = 0; m < " + isa::utils::toString(nrThreads) + "; m++ ) {\n"
	"if ( baseN + get_local_id(0) < " + isa::utils::toString(N) + " ) {\n"
	"tempStorage[(m * " + isa::utils::toString(nrThreads) + ") + get_local_id(0)] = input[((baseM + m) * " + isa::utils::toString(isa::utils::pad(N, padding)) + ") + (baseN + get_local_id(0))];\n"
	"}\n"
	"}\n";
	if ( nrThreads > vector ) {
		*code += "barrier(CLK_LOCAL_MEM_FENCE);\n";
	}
	// Local in-place transpose
	*code += "for ( unsigned int i = 1; i <= " + isa::utils::toString(nrThreads) + " / 2; i++ ) {\n"
	"unsigned int localItem = (get_local_id(0) + i) % " + isa::utils::toString(nrThreads) + ";\n"
	+ typeName + " temp = 0;\n";
	if ( nrThreads == vector ) {
		*code += "if ( (i < "+ isa::utils::toString(nrThreads) + ") || (get_local_id(0) < " + isa::utils::toString(nrThreads) + " / 2) ) {\n";
	} else {
		*code += "if ( (i < "+ isa::utils::toString(nrThreads) + " - " + isa::utils::toString(nrThreads / 2) + ") || (get_local_id(0) < " + isa::utils::toString(nrThreads) + " / 2) ) {\n";
	}
	*code += "temp = tempStorage[(get_local_id(0) * " + isa::utils::toString(nrThreads) + ") + localItem];\n"
	"tempStorage[(get_local_id(0) * " + isa::utils::toString(nrThreads) + ") + localItem] = tempStorage[(localItem * " + isa::utils::toString(nrThreads) + ") + get_local_id(0)];\n"
	"tempStorage[(localItem * " + isa::utils::toString(nrThreads) + ") + get_local_id(0)] = temp;\n"
	"}\n"
	"}\n";
	if ( nrThreads > vector ) {
		*code += "barrier(CLK_LOCAL_MEM_FENCE);\n";
	}
	// Store output
	*code += "for ( unsigned int n = 0; n < " + isa::utils::toString(nrThreads) + "; n++ ) {\n"
	"if ( baseN + n < " + isa::utils::toString(N) + " ) {\n"
	"output[((baseN + n) * " + isa::utils::toString(isa::utils::pad(M, padding)) + ") + (baseM + get_local_id(0))] = tempStorage[(n * " + isa::utils::toString(nrThreads) + ") + get_local_id(0)];"
	"}\n"
	"}\n"
	"}\n";
  // End kernel's template

  return code;
}

} // OpenCl
} // isa

#endif // TRANSPOSE_HPP
<|endoftext|>


<commit_before>/*
M3 -- Meka Robotics Robot Components
Copyright (c) 2010 Meka Robotics
Author: edsinger@mekabot.com (Aaron Edsinger)

M3 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 3 of the License, or
(at your option) any later version.

M3 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 M3.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "m3/chains/head.h"

namespace m3
{

using namespace m3rt;
using namespace std;

bool M3Head::ReadConfig(const char * filename)
{
	if (!M3JointChain::ReadConfig(filename))
		return false;

	YAML::Node doc;
	GetYamlDoc(filename, doc);

	vector<mReal> left_trans;
	vector<mReal> right_trans;
	vector<mReal> left_rot;
	vector<mReal> right_rot;

	doc["eyes"]["right"]["rotation"]>>right_rot;
	doc["eyes"]["right"]["translation"]>>right_trans;
	doc["eyes"]["left"]["rotation"]>>left_rot;
	doc["eyes"]["left"]["translation"]>>left_trans;

	Rotation re_rot;
	Vector re_vec;
	Rotation le_rot;
	Vector le_vec;

	for (int i=0; i<9; i++)
	{
		re_rot.data[i] = right_rot[i];
		le_rot.data[i] = left_rot[i];
	}

	for (int i=0; i<3; i++)
	{
		re_vec[i] = right_trans[i];
		le_vec[i] = left_trans[i];
	}
	left_eye_offset = Frame(le_rot, le_vec);
	right_eye_offset = Frame(re_rot, re_vec);
}

}<commit_msg>Fix a ReadConfig bug in M3Head (no 'true' return on default path).<commit_after>/*
M3 -- Meka Robotics Robot Components
Copyright (c) 2010 Meka Robotics
Author: edsinger@mekabot.com (Aaron Edsinger)

M3 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 3 of the License, or
(at your option) any later version.

M3 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 M3.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "m3/chains/head.h"

namespace m3
{

using namespace m3rt;
using namespace std;

bool M3Head::ReadConfig(const char * filename)
{
	if (!M3JointChain::ReadConfig(filename))
		return false;

	YAML::Node doc;
	GetYamlDoc(filename, doc);

	vector<mReal> left_trans;
	vector<mReal> right_trans;
	vector<mReal> left_rot;
	vector<mReal> right_rot;

	doc["eyes"]["right"]["rotation"]>>right_rot;
	doc["eyes"]["right"]["translation"]>>right_trans;
	doc["eyes"]["left"]["rotation"]>>left_rot;
	doc["eyes"]["left"]["translation"]>>left_trans;

	Rotation re_rot;
	Vector re_vec;
	Rotation le_rot;
	Vector le_vec;

	for (int i=0; i<9; i++)
	{
		re_rot.data[i] = right_rot[i];
		le_rot.data[i] = left_rot[i];
	}

	for (int i=0; i<3; i++)
	{
		re_vec[i] = right_trans[i];
		le_vec[i] = left_trans[i];
	}
	left_eye_offset = Frame(le_rot, le_vec);
	right_eye_offset = Frame(re_rot, re_vec);

    return true;
}

}
<|endoftext|>


<commit_before><commit_msg>remove duplicate include<commit_after><|endoftext|>


<commit_before><commit_msg>fdo#70376: Put only document (file) name in window title on OS X<commit_after><|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Build Suite.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "commandlineparser.h"

#include "command.h"
#include "commandlineoption.h"
#include "commandlineoptionpool.h"
#include "commandpool.h"

#include <logging/logger.h>
#include <logging/translator.h>
#include <tools/buildoptions.h>
#include <tools/error.h>
#include <tools/fileinfo.h>
#include <tools/hostosinfo.h>
#include <tools/platform.h>
#include <tools/settings.h>

#include <QCoreApplication>
#include <QDir>
#include <QTextStream>

#ifdef Q_OS_UNIX
#include <unistd.h>
#endif

namespace qbs {
class CommandLineParser::CommandLineParserPrivate
{
public:
    CommandLineParserPrivate();

    void doParse();
    Command *commandFromString(const QString &commandString) const;
    QList<Command *> allCommands() const;
    QString generalHelp() const;

    void setupProjectFile();
    void setupProgress();
    void setupLogLevel();
    void setupBuildOptions();

    QString propertyName(const QString &aCommandLineName) const;

    QStringList commandLine;
    Command *command;
    QString projectFilePath;
    BuildOptions buildOptions;
    bool showProgress;
    CommandLineOptionPool optionPool;
    CommandPool commandPool;
};

CommandLineParser::CommandLineParser() : d(0)
{
}

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

void CommandLineParser::printHelp() const
{
    QTextStream stream(stdout);

    Q_ASSERT(d->command == d->commandPool.getCommand(HelpCommandType));
    const HelpCommand * const helpCommand = static_cast<HelpCommand *>(d->command);
    if (helpCommand->commandToDescribe().isEmpty()) {
        stream << "qbs " QBS_VERSION "\n";
        stream << d->generalHelp();
    } else {
        const Command * const commandToDescribe
                = d->commandFromString(helpCommand->commandToDescribe());
        stream << commandToDescribe->longDescription();
    }
}

CommandType CommandLineParser::command() const
{
    return d->command->type();
}

QString CommandLineParser::projectFilePath() const
{
    return d->projectFilePath;
}

BuildOptions CommandLineParser::buildOptions() const
{
    return d->buildOptions;
}

QString CommandLineParser::runTargetName() const
{
    Q_ASSERT(d->command->type() == RunCommandType);
    return static_cast<RunCommand *>(d->command)->targetName();
}

QStringList CommandLineParser::runArgs() const
{
    Q_ASSERT(d->command->type() == RunCommandType);
    return static_cast<RunCommand *>(d->command)->targetParameters();
}

QStringList CommandLineParser::products() const
{
    return d->optionPool.productsOption()->arguments();
}

bool CommandLineParser::showProgress() const
{
    return d->showProgress;
}

QString CommandLineParser::commandName() const
{
    return d->command->representation();
}

QString CommandLineParser::commandDescription() const
{
    return d->command->longDescription();
}

QList<QVariantMap> CommandLineParser::buildConfigurations() const
{
    // Key: build variant, value: properties. Empty key used for global properties.
    typedef QMap<QString, QVariantMap> PropertyMaps;
    PropertyMaps properties;

    const QString buildVariantKey = QLatin1String("qbs.buildVariant");
    QString currentKey = QString();
    QVariantMap currentProperties;
    foreach (const QString &arg, d->command->additionalArguments()) {
        const int sepPos = arg.indexOf(QLatin1Char(':'));
        if (sepPos == -1) { // New build variant found.
            properties.insert(currentKey, currentProperties);
            currentKey = arg;
            currentProperties.clear();
            continue;
        }
        const QString property = d->propertyName(arg.left(sepPos));
        if (property.isEmpty())
            qbsWarning() << Tr::tr("Ignoring empty property.");
        else if (property == buildVariantKey)
            qbsWarning() << Tr::tr("Refusing to overwrite special property '%1'.").arg(buildVariantKey);
        else
            currentProperties.insert(property, arg.mid(sepPos + 1));
    }
    properties.insert(currentKey, currentProperties);

    if (properties.count() == 1) // No build variant specified on command line.
        properties.insert(Settings().buildVariant(), QVariantMap());

    const PropertyMaps::Iterator globalMapIt = properties.find(QString());
    Q_ASSERT(globalMapIt != properties.end());
    const QVariantMap globalProperties = globalMapIt.value();
    properties.erase(globalMapIt);

    QList<QVariantMap> buildConfigs;
    for (PropertyMaps::ConstIterator mapsIt = properties.constBegin();
             mapsIt != properties.constEnd(); ++mapsIt) {
        QVariantMap properties = mapsIt.value();
        for (QVariantMap::ConstIterator globalPropIt = globalProperties.constBegin();
                 globalPropIt != globalProperties.constEnd(); ++globalPropIt) {
            properties.insert(globalPropIt.key(), globalPropIt.value());
        }
        properties.insert(buildVariantKey, mapsIt.key());
        buildConfigs << properties;
    }

    return buildConfigs;
}

bool CommandLineParser::parseCommandLine(const QStringList &args)
{
    delete d;
    d = new CommandLineParserPrivate;
    d->commandLine = args;
    try {
        d->doParse();
        return true;
    } catch (const Error &error) {
        qbsError() << error.toString();
        return false;
    }
}

CommandLineParser::CommandLineParserPrivate::CommandLineParserPrivate()
    : command(0), showProgress(false), commandPool(optionPool)
{
}

void CommandLineParser::CommandLineParserPrivate::doParse()
{
    if (commandLine.isEmpty()) { // No command given, use default.
        command = commandPool.getCommand(BuildCommandType);
    } else {
        try {
            command = commandFromString(commandLine.first());
            commandLine.removeFirst();
        } catch (const Error &) { // No command given, use default.
            command = commandPool.getCommand(BuildCommandType);
        }
    }
    command->parse(commandLine);

    if (command->type() == HelpCommandType)
        return;

    setupProjectFile();
    setupProgress();
    setupLogLevel();
    setupBuildOptions();
}

Command *CommandLineParser::CommandLineParserPrivate::commandFromString(const QString &commandString) const
{
    foreach (Command * const command, allCommands()) {
        if (command->representation() == commandString) {
            return command;
        }
    }
    throw Error(Tr::tr("No such command '%1'.\n%2").arg(commandString), generalHelp());
}

QList<Command *> CommandLineParser::CommandLineParserPrivate::allCommands() const
{
    return QList<Command *>()
            << commandPool.getCommand(BuildCommandType)
            << commandPool.getCommand(CleanCommandType)
            << commandPool.getCommand(RunCommandType)
            << commandPool.getCommand(ShellCommandType)
            << commandPool.getCommand(PropertiesCommandType)
            << commandPool.getCommand(StatusCommandType)
            << commandPool.getCommand(HelpCommandType);
}

QString CommandLineParser::CommandLineParserPrivate::generalHelp() const
{
    QString help = Tr::tr("Usage: qbs [command] [command parameters]\n");
    help += Tr::tr("The commands are:\n");
    foreach (const Command * command, allCommands()) {
        help.append(QLatin1String("  ")).append(command->representation());
        const QString indentation
                = QString(15 - command->representation().count(), QLatin1Char(' '));
        help.append(indentation).append(command->shortDescription()).append(QLatin1Char('\n'));
    }
    return help;
}

void CommandLineParser::CommandLineParserPrivate::setupProjectFile()
{
    projectFilePath = optionPool.fileOption()->projectFilePath();
    if (projectFilePath.isEmpty()) {
        qbsDebug() << "No project file given; looking in current directory.";
        projectFilePath = QDir::currentPath();
    }

    const QFileInfo projectFileInfo(projectFilePath);
    if (!projectFileInfo.exists())
        throw Error(Tr::tr("Project file '%1' cannot be found.").arg(projectFilePath));
    if (projectFileInfo.isFile())
        return;
    if (!projectFileInfo.isDir())
        throw Error(Tr::tr("Project file '%1' has invalid type.").arg(projectFilePath));

    // TODO: Remove check for '.qbp' in 0.4.
    const QStringList namePatterns = QStringList()
            << QLatin1String("*.qbp") << QLatin1String("*.qbs");

    const QStringList &actualFileNames
            = QDir(projectFilePath).entryList(namePatterns, QDir::Files);
    if (actualFileNames.isEmpty()) {
        QString error;
        if (optionPool.fileOption()->projectFilePath().isEmpty()) {
            error = Tr::tr("No project file given and none found in current directory.\n");
            error += Tr::tr("Usage: %1").arg(command->longDescription());
        } else {
            error = Tr::tr("No project file found in directory '%1'.").arg(projectFilePath);
        }
        throw Error(error);
    }
    if (actualFileNames.count() > 1) {
        throw Error(Tr::tr("More than one project file found in directory '%1'.")
                .arg(projectFilePath));
    }
    projectFilePath.append(QLatin1Char('/')).append(actualFileNames.first());

    projectFilePath = FileInfo::resolvePath(QDir::currentPath(), projectFilePath);
    projectFilePath = QDir::cleanPath(projectFilePath);

    // TODO: Remove in 0.4
    if (projectFilePath.endsWith(QLatin1String(".qbp")))
        qbsInfo() << Tr::tr("Your main project file has the old suffix '.qbp'. This does not "
                        "hurt, but the convention is now to use '.qbs'.");

    qbsDebug() << DontPrintLogLevel << "Using project file '"
               << QDir::toNativeSeparators(projectFilePath) << "'.";
}

void CommandLineParser::CommandLineParserPrivate::setupBuildOptions()
{
    buildOptions.dryRun = optionPool.dryRunOption()->enabled();
    buildOptions.changedFiles = optionPool.changedFilesOption()->arguments();
    QDir currentDir;
    for (int i = 0; i < buildOptions.changedFiles.count(); ++i) {
        QString &file = buildOptions.changedFiles[i];
        file = QDir::fromNativeSeparators(currentDir.absoluteFilePath(file));
    }
    buildOptions.keepGoing = optionPool.keepGoingOption()->enabled();
    const JobsOption * jobsOption = optionPool.jobsOption();
    if (jobsOption->jobCount() != 0)
        buildOptions.maxJobCount = jobsOption->jobCount();
}

void CommandLineParser::CommandLineParserPrivate::setupProgress()
{
    const ShowProgressOption * const option = optionPool.showProgressOption();
    showProgress = option->enabled();
#ifdef Q_OS_UNIX
    if (!isatty(STDOUT_FILENO)) {
        showProgress = false;
        qbsWarning() << Tr::tr("Ignoring option '%1', because standard output is "
                               "not connected to a terminal.").arg(option->longRepresentation());
    }
#endif
}

void CommandLineParser::CommandLineParserPrivate::setupLogLevel()
{
    const LogLevelOption * const logLevelOption = optionPool.logLevelOption();
    const VerboseOption * const verboseOption = optionPool.verboseOption();
    const QuietOption * const quietOption = optionPool.quietOption();
    int logLevel = logLevelOption->logLevel();
    logLevel += verboseOption->count();
    logLevel -= quietOption->count();

    if (showProgress && logLevel != LoggerMinLevel) {
        const bool logLevelWasSetByUser
                = logLevelOption->logLevel() != Logger::defaultLevel()
                || verboseOption->count() > 0 || quietOption->count() > 0;
        if (logLevelWasSetByUser) {
            qbsInfo() << Tr::tr("Setting log level to '%1', because option '%2'"
                                " has been given.").arg(Logger::logLevelName(LoggerMinLevel),
                                optionPool.showProgressOption()->longRepresentation());
        }
        logLevel = LoggerMinLevel;
    }
    if (logLevel < LoggerMinLevel) {
        qbsWarning() << Tr::tr("Cannot decrease log level as much as specified; using '%1'.")
                .arg(Logger::logLevelName(LoggerMinLevel));
        logLevel = LoggerMinLevel;
    } else if (logLevel > LoggerMaxLevel) {
        qbsWarning() << Tr::tr("Cannot increase log level as much as specified; using '%1'.")
                .arg(Logger::logLevelName(LoggerMaxLevel));
        logLevel = LoggerMaxLevel;
    }
    Logger::instance().setLevel(logLevel);
}

QString CommandLineParser::CommandLineParserPrivate::propertyName(const QString &aCommandLineName) const
{
    // Make fully-qualified, ie "platform" -> "qbs.platform"
    if (aCommandLineName.contains("."))
        return aCommandLineName;
    else
        return "qbs." + aCommandLineName;
}

} // namespace qbs
<commit_msg>Fix minor bug in command line parser.<commit_after>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Build Suite.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "commandlineparser.h"

#include "command.h"
#include "commandlineoption.h"
#include "commandlineoptionpool.h"
#include "commandpool.h"

#include <logging/logger.h>
#include <logging/translator.h>
#include <tools/buildoptions.h>
#include <tools/error.h>
#include <tools/fileinfo.h>
#include <tools/hostosinfo.h>
#include <tools/platform.h>
#include <tools/settings.h>

#include <QCoreApplication>
#include <QDir>
#include <QTextStream>

#ifdef Q_OS_UNIX
#include <unistd.h>
#endif

namespace qbs {
class CommandLineParser::CommandLineParserPrivate
{
public:
    CommandLineParserPrivate();

    void doParse();
    Command *commandFromString(const QString &commandString) const;
    QList<Command *> allCommands() const;
    QString generalHelp() const;

    void setupProjectFile();
    void setupProgress();
    void setupLogLevel();
    void setupBuildOptions();

    QString propertyName(const QString &aCommandLineName) const;

    QStringList commandLine;
    Command *command;
    QString projectFilePath;
    BuildOptions buildOptions;
    bool showProgress;
    CommandLineOptionPool optionPool;
    CommandPool commandPool;
};

CommandLineParser::CommandLineParser() : d(0)
{
}

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

void CommandLineParser::printHelp() const
{
    QTextStream stream(stdout);

    Q_ASSERT(d->command == d->commandPool.getCommand(HelpCommandType));
    const HelpCommand * const helpCommand = static_cast<HelpCommand *>(d->command);
    if (helpCommand->commandToDescribe().isEmpty()) {
        stream << "qbs " QBS_VERSION "\n";
        stream << d->generalHelp();
    } else {
        const Command * const commandToDescribe
                = d->commandFromString(helpCommand->commandToDescribe());
        stream << commandToDescribe->longDescription();
    }
}

CommandType CommandLineParser::command() const
{
    return d->command->type();
}

QString CommandLineParser::projectFilePath() const
{
    return d->projectFilePath;
}

BuildOptions CommandLineParser::buildOptions() const
{
    return d->buildOptions;
}

QString CommandLineParser::runTargetName() const
{
    Q_ASSERT(d->command->type() == RunCommandType);
    return static_cast<RunCommand *>(d->command)->targetName();
}

QStringList CommandLineParser::runArgs() const
{
    Q_ASSERT(d->command->type() == RunCommandType);
    return static_cast<RunCommand *>(d->command)->targetParameters();
}

QStringList CommandLineParser::products() const
{
    return d->optionPool.productsOption()->arguments();
}

bool CommandLineParser::showProgress() const
{
    return d->showProgress;
}

QString CommandLineParser::commandName() const
{
    return d->command->representation();
}

QString CommandLineParser::commandDescription() const
{
    return d->command->longDescription();
}

QList<QVariantMap> CommandLineParser::buildConfigurations() const
{
    // Key: build variant, value: properties. Empty key used for global properties.
    typedef QMap<QString, QVariantMap> PropertyMaps;
    PropertyMaps properties;

    const QString buildVariantKey = QLatin1String("qbs.buildVariant");
    QString currentKey = QString();
    QVariantMap currentProperties;
    foreach (const QString &arg, d->command->additionalArguments()) {
        const int sepPos = arg.indexOf(QLatin1Char(':'));
        if (sepPos == -1) { // New build variant found.
            properties.insert(currentKey, currentProperties);
            currentKey = arg;
            currentProperties.clear();
            continue;
        }
        const QString property = d->propertyName(arg.left(sepPos));
        if (property.isEmpty())
            qbsWarning() << Tr::tr("Ignoring empty property.");
        else if (property == buildVariantKey)
            qbsWarning() << Tr::tr("Refusing to overwrite special property '%1'.").arg(buildVariantKey);
        else
            currentProperties.insert(property, arg.mid(sepPos + 1));
    }
    properties.insert(currentKey, currentProperties);

    if (properties.count() == 1) // No build variant specified on command line.
        properties.insert(Settings().buildVariant(), QVariantMap());

    const PropertyMaps::Iterator globalMapIt = properties.find(QString());
    Q_ASSERT(globalMapIt != properties.end());
    const QVariantMap globalProperties = globalMapIt.value();
    properties.erase(globalMapIt);

    QList<QVariantMap> buildConfigs;
    for (PropertyMaps::ConstIterator mapsIt = properties.constBegin();
             mapsIt != properties.constEnd(); ++mapsIt) {
        QVariantMap properties = mapsIt.value();
        for (QVariantMap::ConstIterator globalPropIt = globalProperties.constBegin();
                 globalPropIt != globalProperties.constEnd(); ++globalPropIt) {
            properties.insert(globalPropIt.key(), globalPropIt.value());
        }
        properties.insert(buildVariantKey, mapsIt.key());
        buildConfigs << properties;
    }

    return buildConfigs;
}

bool CommandLineParser::parseCommandLine(const QStringList &args)
{
    delete d;
    d = new CommandLineParserPrivate;
    d->commandLine = args;
    try {
        d->doParse();
        return true;
    } catch (const Error &error) {
        qbsError() << error.toString();
        return false;
    }
}

CommandLineParser::CommandLineParserPrivate::CommandLineParserPrivate()
    : command(0), showProgress(false), commandPool(optionPool)
{
}

void CommandLineParser::CommandLineParserPrivate::doParse()
{
    if (commandLine.isEmpty()) { // No command given, use default.
        command = commandPool.getCommand(BuildCommandType);
    } else {
        try {
            command = commandFromString(commandLine.first());
            commandLine.removeFirst();
        } catch (const Error &) { // No command given, use default.
            command = commandPool.getCommand(BuildCommandType);
        }
    }
    command->parse(commandLine);

    if (command->type() == HelpCommandType)
        return;

    setupProjectFile();
    setupProgress();
    setupLogLevel();
    setupBuildOptions();
}

Command *CommandLineParser::CommandLineParserPrivate::commandFromString(const QString &commandString) const
{
    foreach (Command * const command, allCommands()) {
        if (command->representation() == commandString) {
            return command;
        }
    }
    throw Error(Tr::tr("No such command '%1'.\n%2").arg(commandString), generalHelp());
}

QList<Command *> CommandLineParser::CommandLineParserPrivate::allCommands() const
{
    return QList<Command *>()
            << commandPool.getCommand(BuildCommandType)
            << commandPool.getCommand(CleanCommandType)
            << commandPool.getCommand(RunCommandType)
            << commandPool.getCommand(ShellCommandType)
            << commandPool.getCommand(PropertiesCommandType)
            << commandPool.getCommand(StatusCommandType)
            << commandPool.getCommand(HelpCommandType);
}

QString CommandLineParser::CommandLineParserPrivate::generalHelp() const
{
    QString help = Tr::tr("Usage: qbs [command] [command parameters]\n");
    help += Tr::tr("The commands are:\n");
    foreach (const Command * command, allCommands()) {
        help.append(QLatin1String("  ")).append(command->representation());
        const QString indentation
                = QString(15 - command->representation().count(), QLatin1Char(' '));
        help.append(indentation).append(command->shortDescription()).append(QLatin1Char('\n'));
    }
    return help;
}

void CommandLineParser::CommandLineParserPrivate::setupProjectFile()
{
    projectFilePath = optionPool.fileOption()->projectFilePath();
    if (projectFilePath.isEmpty()) {
        qbsDebug() << "No project file given; looking in current directory.";
        projectFilePath = QDir::currentPath();
    }

    const QFileInfo projectFileInfo(projectFilePath);
    if (!projectFileInfo.exists())
        throw Error(Tr::tr("Project file '%1' cannot be found.").arg(projectFilePath));
    if (projectFileInfo.isFile())
        return;
    if (!projectFileInfo.isDir())
        throw Error(Tr::tr("Project file '%1' has invalid type.").arg(projectFilePath));

    // TODO: Remove check for '.qbp' in 0.4.
    const QStringList namePatterns = QStringList()
            << QLatin1String("*.qbp") << QLatin1String("*.qbs");

    const QStringList &actualFileNames
            = QDir(projectFilePath).entryList(namePatterns, QDir::Files);
    if (actualFileNames.isEmpty()) {
        QString error;
        if (optionPool.fileOption()->projectFilePath().isEmpty()) {
            error = Tr::tr("No project file given and none found in current directory.\n");
            error += Tr::tr("Usage: %1").arg(command->longDescription());
        } else {
            error = Tr::tr("No project file found in directory '%1'.").arg(projectFilePath);
        }
        throw Error(error);
    }
    if (actualFileNames.count() > 1) {
        throw Error(Tr::tr("More than one project file found in directory '%1'.")
                .arg(projectFilePath));
    }
    projectFilePath.append(QLatin1Char('/')).append(actualFileNames.first());

    projectFilePath = FileInfo::resolvePath(QDir::currentPath(), projectFilePath);
    projectFilePath = QDir::cleanPath(projectFilePath);

    // TODO: Remove in 0.4
    if (projectFilePath.endsWith(QLatin1String(".qbp")))
        qbsInfo() << Tr::tr("Your main project file has the old suffix '.qbp'. This does not "
                        "hurt, but the convention is now to use '.qbs'.");

    qbsDebug() << DontPrintLogLevel << "Using project file '"
               << QDir::toNativeSeparators(projectFilePath) << "'.";
}

void CommandLineParser::CommandLineParserPrivate::setupBuildOptions()
{
    buildOptions.dryRun = optionPool.dryRunOption()->enabled();
    buildOptions.changedFiles = optionPool.changedFilesOption()->arguments();
    QDir currentDir;
    for (int i = 0; i < buildOptions.changedFiles.count(); ++i) {
        QString &file = buildOptions.changedFiles[i];
        file = QDir::fromNativeSeparators(currentDir.absoluteFilePath(file));
    }
    buildOptions.keepGoing = optionPool.keepGoingOption()->enabled();
    const JobsOption * jobsOption = optionPool.jobsOption();
    if (jobsOption->jobCount() != 0)
        buildOptions.maxJobCount = jobsOption->jobCount();
}

void CommandLineParser::CommandLineParserPrivate::setupProgress()
{
    const ShowProgressOption * const option = optionPool.showProgressOption();
    showProgress = option->enabled();
#ifdef Q_OS_UNIX
    if (showProgress && !isatty(STDOUT_FILENO)) {
        showProgress = false;
        qbsWarning() << Tr::tr("Ignoring option '%1', because standard output is "
                               "not connected to a terminal.").arg(option->longRepresentation());
    }
#endif
}

void CommandLineParser::CommandLineParserPrivate::setupLogLevel()
{
    const LogLevelOption * const logLevelOption = optionPool.logLevelOption();
    const VerboseOption * const verboseOption = optionPool.verboseOption();
    const QuietOption * const quietOption = optionPool.quietOption();
    int logLevel = logLevelOption->logLevel();
    logLevel += verboseOption->count();
    logLevel -= quietOption->count();

    if (showProgress && logLevel != LoggerMinLevel) {
        const bool logLevelWasSetByUser
                = logLevelOption->logLevel() != Logger::defaultLevel()
                || verboseOption->count() > 0 || quietOption->count() > 0;
        if (logLevelWasSetByUser) {
            qbsInfo() << Tr::tr("Setting log level to '%1', because option '%2'"
                                " has been given.").arg(Logger::logLevelName(LoggerMinLevel),
                                optionPool.showProgressOption()->longRepresentation());
        }
        logLevel = LoggerMinLevel;
    }
    if (logLevel < LoggerMinLevel) {
        qbsWarning() << Tr::tr("Cannot decrease log level as much as specified; using '%1'.")
                .arg(Logger::logLevelName(LoggerMinLevel));
        logLevel = LoggerMinLevel;
    } else if (logLevel > LoggerMaxLevel) {
        qbsWarning() << Tr::tr("Cannot increase log level as much as specified; using '%1'.")
                .arg(Logger::logLevelName(LoggerMaxLevel));
        logLevel = LoggerMaxLevel;
    }
    Logger::instance().setLevel(logLevel);
}

QString CommandLineParser::CommandLineParserPrivate::propertyName(const QString &aCommandLineName) const
{
    // Make fully-qualified, ie "platform" -> "qbs.platform"
    if (aCommandLineName.contains("."))
        return aCommandLineName;
    else
        return "qbs." + aCommandLineName;
}

} // namespace qbs
<|endoftext|>


<commit_before>#include <catch.hpp>
#include "Preset.hpp"
#include "Config.hpp"
#include <test_options.hpp>

using namespace Slic3r::GUI;
using namespace std::literals::string_literals;

SCENARIO( "Preset construction" ) {
    GIVEN("A preset file with at least one configuration") {
        WHEN( "Preset is constructed." ) {
            Preset item {std::string(testfile_dir) + "test_preset", "preset_load_numeric.ini"s, preset_t::Print};
            THEN("Name is preset_load_numeric") {
                REQUIRE(item.name == "preset_load_numeric"s);
            }
            THEN("group is Print") {
                REQUIRE(item.group == preset_t::Print);
            }
            THEN("preset default is false.") {
                REQUIRE(item.default_preset == false);
            }
        }
    }
    GIVEN("A default preset construction") {
        WHEN( "Preset is constructed." ) {
            Preset item {true, "- default -", preset_t::Print};
            THEN("Name is - default -") {
                REQUIRE(item.name == "- default -"s);
            }
            THEN("group is Print") {
                REQUIRE(item.group == preset_t::Print);
            }
            THEN("preset default is true.") {
                REQUIRE(item.default_preset == true);
            }
            THEN("file_exists() is false") {
                REQUIRE(item.file_exists() == false);
            }
        }
    }
}
SCENARIO( "Preset loading" ) {
    GIVEN("A preset file with a config item that has adaptive_slicing = 1") {
        Preset item {std::string(testfile_dir) + "test_preset", "preset_load_numeric.ini"s, preset_t::Print};
        THEN("file_exists() returns true") {
            REQUIRE(item.file_exists() == true);
        }
        config_ptr ref;
        WHEN("The preset file with one item is loaded") {
            ref = item.load_config();
            THEN("Config is not dirty.") {
                REQUIRE(item.dirty() == false);
            }
            THEN("adaptive_slicing = 1 in the preset config") {
                REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == true);
            }
        }
        auto config { Slic3r::Config::new_from_defaults() };
        ref = item.load_config();
        WHEN("Option is changed in the config via loading a config") {
            // precondition: adaptive_slicing is still true
            REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == true);
            // precondition: default option for adaptice_slicing is false
            REQUIRE(config->get<ConfigOptionBool>("adaptive_slicing").getBool() == false);
            ref->apply(config);
            THEN("Config is dirty.") {
                REQUIRE(item.dirty() == true);
            }
            THEN("adaptive_slicing = 0 in the preset config") {
                REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == false);
            }
            THEN("subsequent calls yield the same reference") {
                REQUIRE(item.load_config() == ref);
            }
        }
    }
    GIVEN("A preset file with a config item that has adaptive_slicing = 1 and default_preset = true") {
        Preset item {std::string(testfile_dir) + "test_preset", "preset_load_numeric.ini"s, preset_t::Print};
        item.default_preset = true;
        config_ptr ref;
        WHEN("The preset file with one item is loaded") {
            ref = item.load_config();
            THEN("Config is not dirty.") {
                REQUIRE(item.dirty() == false);
            }
            THEN("adaptive_slicing = 0 in the preset config") {
                REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == false);
            }
            THEN("loaded is true") {
                REQUIRE(item.loaded() == true);
            }
            THEN("subsequent calls yield the same reference") {
                REQUIRE(item.load_config() == ref);
            }
        }
        ref = item.load_config();
        WHEN("Option is changed in the config") {
            ref->set("adaptive_slicing", true);
            THEN("Config is dirty.") {
                REQUIRE(item.dirty() == true);
            }
            THEN("adaptive_slicing = 1 in the preset config") {
                REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == true);
            }
        }
    }
    GIVEN("An invalid preset file") {
        Preset item {std::string(testfile_dir) + "test_preset", "___invalid__preset_load_numeric.ini"s, preset_t::Print};
        THEN("file_exists() returns false") {
            REQUIRE(item.file_exists() == false);
        }
        THEN("loaded is false") {
            REQUIRE(item.loaded() == false);
        }
    }
}
<commit_msg>test default construction requirements for Presets.<commit_after>#include <catch.hpp>
#include "Preset.hpp"
#include "Config.hpp"
#include <test_options.hpp>

using namespace Slic3r::GUI;
using namespace std::literals::string_literals;

SCENARIO( "Preset construction" ) {
    GIVEN("A preset file with at least one configuration") {
        WHEN( "Preset is constructed." ) {
            Preset item {std::string(testfile_dir) + "test_preset", "preset_load_numeric.ini"s, preset_t::Print};
            THEN("Name is preset_load_numeric") {
                REQUIRE(item.name == "preset_load_numeric"s);
            }
            THEN("group is Print") {
                REQUIRE(item.group == preset_t::Print);
            }
            THEN("preset default is false.") {
                REQUIRE(item.default_preset == false);
            }
        }
    }
    GIVEN("A default preset construction for Print") {
        WHEN( "Preset is constructed." ) {
            Preset item {true, "- default -", preset_t::Print};
            THEN("Name is - default -") {
                REQUIRE(item.name == "- default -"s);
            }
            THEN("group is Print") {
                REQUIRE(item.group == preset_t::Print);
            }
            THEN("preset default is true.") {
                REQUIRE(item.default_preset == true);
            }
            THEN("file_exists() is false") {
                REQUIRE(item.file_exists() == false);
            }
            THEN("Does not contain filament_colour (a material option)") {
                if (auto config = item.config().lock()) {
                    REQUIRE(!config->has("filament_colours"));
                }
            }
            THEN("Does not contain extruders (a printer option)") {
                if (auto config = item.config().lock()) {
                    REQUIRE(!config->has("extruders"));
                }
            }
            THEN("Does contain layer_height (a print option)") {
                if (auto config = item.config().lock()) {
                    REQUIRE(config->has("layer_height"));
                }
            }
        }
    }
    GIVEN("A default preset construction for Material") {
        WHEN( "Preset is constructed." ) {
            Preset item {true, "- default -", preset_t::Material};
            THEN("Name is - default -") {
                REQUIRE(item.name == "- default -"s);
            }
            THEN("group is Material") {
                REQUIRE(item.group == preset_t::Material);
            }
            THEN("preset default is true.") {
                REQUIRE(item.default_preset == true);
            }
            THEN("file_exists() is false") {
                REQUIRE(item.file_exists() == false);
            }
            THEN("Does contain filament_colour (a material option)") {
                if (auto config = item.config().lock()) {
                    REQUIRE(config->has("filament_colours"));
                }
            }
            THEN("Does not contain extruders (a printer option)") {
                if (auto config = item.config().lock()) {
                    REQUIRE(!config->has("extruders"));
                }
            }
            THEN("Does not contain layer_height (a print option)") {
                if (auto config = item.config().lock()) {
                    REQUIRE(!config->has("layer_height"));
                }
            }
        }
    }
    GIVEN("A default preset construction for Printer") {
        WHEN( "Preset is constructed." ) {
            Preset item {true, "- default -", preset_t::Printer};
            THEN("Name is - default -") {
                REQUIRE(item.name == "- default -"s);
            }
            THEN("group is Printer") {
                REQUIRE(item.group == preset_t::Printer);
            }
            THEN("preset default is true.") {
                REQUIRE(item.default_preset == true);
            }
            THEN("file_exists() is false") {
                REQUIRE(item.file_exists() == false);
            }
            THEN("Does not contain filament_colour (a material option)") {
                if (auto config = item.config().lock()) {
                    REQUIRE(!config->has("filament_colours"));
                }
            }
            THEN("Does contain extruders (a printer option)") {
                if (auto config = item.config().lock()) {
                    REQUIRE(config->has("extruders"));
                }
            }
            THEN("Does not contain layer_height (a print option)") {
                if (auto config = item.config().lock()) {
                    REQUIRE(!config->has("layer_height"));
                }
            }
        }
    }
}
SCENARIO( "Preset loading" ) {
    GIVEN("A preset file with a config item that has adaptive_slicing = 1") {
        Preset item {std::string(testfile_dir) + "test_preset", "preset_load_numeric.ini"s, preset_t::Print};
        THEN("file_exists() returns true") {
            REQUIRE(item.file_exists() == true);
        }
        config_ptr ref;
        WHEN("The preset file with one item is loaded") {
            ref = item.load_config();
            THEN("Config is not dirty.") {
                REQUIRE(item.dirty() == false);
            }
            THEN("adaptive_slicing = 1 in the preset config") {
                REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == true);
            }
        }
        auto config { Slic3r::Config::new_from_defaults() };
        ref = item.load_config();
        WHEN("Option is changed in the config via loading a config") {
            // precondition: adaptive_slicing is still true
            REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == true);
            // precondition: default option for adaptice_slicing is false
            REQUIRE(config->get<ConfigOptionBool>("adaptive_slicing").getBool() == false);
            ref->apply(config);
            THEN("Config is dirty.") {
                REQUIRE(item.dirty() == true);
            }
            THEN("adaptive_slicing = 0 in the preset config") {
                REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == false);
            }
            THEN("subsequent calls yield the same reference") {
                REQUIRE(item.load_config() == ref);
            }
        }
    }
    GIVEN("A preset file with a config item that has adaptive_slicing = 1 and default_preset = true") {
        Preset item {std::string(testfile_dir) + "test_preset", "preset_load_numeric.ini"s, preset_t::Print};
        item.default_preset = true;
        config_ptr ref;
        WHEN("The preset file with one item is loaded") {
            ref = item.load_config();
            THEN("Config is not dirty.") {
                REQUIRE(item.dirty() == false);
            }
            THEN("adaptive_slicing = 0 in the preset config") {
                REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == false);
            }
            THEN("loaded is true") {
                REQUIRE(item.loaded() == true);
            }
            THEN("subsequent calls yield the same reference") {
                REQUIRE(item.load_config() == ref);
            }
        }
        ref = item.load_config();
        WHEN("Option is changed in the config") {
            ref->set("adaptive_slicing", true);
            THEN("Config is dirty.") {
                REQUIRE(item.dirty() == true);
            }
            THEN("adaptive_slicing = 1 in the preset config") {
                REQUIRE(item.dirty_config().get<ConfigOptionBool>("adaptive_slicing").getBool() == true);
            }
        }
    }
    GIVEN("An invalid preset file") {
        Preset item {std::string(testfile_dir) + "test_preset", "___invalid__preset_load_numeric.ini"s, preset_t::Print};
        THEN("file_exists() returns false") {
            REQUIRE(item.file_exists() == false);
        }
        THEN("loaded is false") {
            REQUIRE(item.loaded() == false);
        }
    }
}
<|endoftext|>


<commit_before>#include <cassert>
#include <ctime>
#include <iostream>
#include <cstdlib>
#include <vector>

#include "../slitherlink/SlitherlinkDatabase.h"
#include "../slitherlink/SlitherlinkDatabaseMethod.hpp"
#include "../slitherlink/SlitherlinkField.h"
#include "../slitherlink/SlitherlinkProblem.h"
#include "Test.h"

namespace Penciloid
{
void PenciloidTest::SlitherlinkClueTest(int height, int width, std::vector<const char*> board, int expected_status, int test_id = -1)
{
	SlitherlinkField field;
	field.Init(height, width);

	for (int y = 0; y < height; ++y) {
		for (int x = 0; x < width; ++x) {
			char clue = board[y * 2 + 1][x * 2 + 1];
			if ('0' <= clue && clue <= '3') field.SetClue(y, x, clue - '0');
		}
	}

	field.CheckAll();

	bool is_status_ok = true;
	if (expected_status == SolverStatus::NORMAL && field.GetStatus() != expected_status) is_status_ok = false;
	if (expected_status == SolverStatus::SUCCESS && field.GetStatus() != expected_status) is_status_ok = false;
	if (expected_status == SolverStatus::INCONSISTENT && (field.GetStatus() & SolverStatus::INCONSISTENT) == 0) is_status_ok = false;

	if (!is_status_ok) {
		std::cerr << "SlitherlinkClueTest failed in test #" << test_id << std::endl;
		std::cerr << "expected: " << expected_status << ", actual: " << field.GetStatus() << " (field status)" << std::endl;
	}

	if (expected_status == SolverStatus::INCONSISTENT) return;

	for (int y = 0; y <= height * 2; ++y) {
		for (int x = 0; x <= width * 2; ++x) {
			if (y % 2 == x % 2) continue; // this is not a segment

			int expected =
				board[y][x] == ' ' ? SlitherlinkField::LOOP_UNDECIDED :
				board[y][x] == 'x' ? SlitherlinkField::LOOP_BLANK : SlitherlinkField::LOOP_LINE;

			if (field.GetSegmentStyle(y, x) != expected) {
				std::cerr << "SlitherlinkClueTest failed in test #" << test_id << std::endl;
				std::cerr << "expected: " << expected << ", actual: " << field.GetSegmentStyle(y, x) << " at (" << y << "," << x << ")" << std::endl;
				exit(1);
			}
		}
	}
}

bool PenciloidTest::SlitherlinkCheckGrid(SlitherlinkField &field, const int *expected)
{
	int height = field.GetHeight() * 2 + 1, width = field.GetWidth() * 2 + 1;

	for (int i = 0; i < height; ++i) {
		for (int j = 0; j < width; ++j) {
			if (i % 2 != j % 2) {
				int expected_style = (expected[i * width + j] == 1) ? SlitherlinkField::LOOP_LINE : SlitherlinkField::LOOP_BLANK;
				if (field.GetSegmentStyle(i, j) != expected_style) return false;
			}
		}
	}

	return true;
}

void PenciloidTest::SlitherlinkFieldTestByProblems()
{
	for (int t = 0; t < 2; ++t) {
		// t: enable database or not
		// t is specified in test_id by adding t * 1000

		if (t == 0) {
			if (SlitherlinkDatabase::IsCreated()) SlitherlinkDatabase::ReleaseDatabase();
		} else if (t == 1) {
			if (!SlitherlinkDatabase::IsCreated()) SlitherlinkDatabase::CreateDatabase();
		}

		SlitherlinkClueTest(3, 3, {
			"+x+x+-+",
			"x0x2| |",
			"+x+-+x+",
			"x | x |",
			"+-+x+x+",
			"|3x1x |",
			"+-+-+-+",
		}, SolverStatus::SUCCESS, t * 1000 + 0);

		SlitherlinkClueTest(3, 3, {
			"+-+-+-+",
			"| x x |",
			"+x+-+x+",
			"|3|3| |",
			"+-+x+x+",
			"x x |3|",
			"+x+x+-+",
		}, SolverStatus::SUCCESS, t * 1000 + 1);

		// 2: closed loop test
		SlitherlinkClueTest(5, 3, {
			"+-+x+-+",
			"|3|3|3|",
			"+x+-+x+",
			"|2x2x2|",
			"+-+-+-+",
			"x x1x x",
			"+x+x+x+",
			"x x x x",
			"+x+x+x+",
			"x x x x",
			"+x+x+x+",
		}, SolverStatus::SUCCESS, t * 1000 + 2);

		// 3: closed loop (inconsistent) test
		SlitherlinkClueTest(5, 3, {
			"+ + + +",
			" 3 3 3 ",
			"+ + + +",
			" 2 2 2 ",
			"+ + + +",
			"       ",
			"+ + + +",
			"     2 ",
			"+ + + +",
			"       ",
			"+ + + +",
		}, SolverStatus::INCONSISTENT, t * 1000 + 3);

		// 1xx: diagonal chain test
		SlitherlinkClueTest(4, 4, {
			"+x+x+ + +",
			"x0x      ",
			"+x+ + + +",
			"x  2     ",
			"+ + +x+ +",
			"    x1   ",
			"+ + + + +",
			"         ",
			"+ + + + +",
		}, SolverStatus::NORMAL, t * 1000 + 100);

		SlitherlinkClueTest(4, 4, {
			"+x+x+ + +",
			"x0x      ",
			"+x+-+ + +",
			"x |2x    ",
			"+ +x+-+ +",
			"    |3   ",
			"+ + + + +",
			"         ",
			"+ + + + +",
		}, SolverStatus::NORMAL, t * 1000 + 101);

		if (t == 1) SlitherlinkDatabase::ReleaseDatabase();
	}
}

void PenciloidTest::SlitherlinkReducedDatabaseTest()
{
	if (SlitherlinkDatabase::IsCreated()) SlitherlinkDatabase::ReleaseDatabase();
	SlitherlinkDatabase::CreateReducedDatabase(SlitherlinkDatabaseMethod());

	SlitherlinkClueTest(4, 4, {
		"+x+ + + +",
		"x1       ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
	}, SolverStatus::NORMAL, 2000);

	SlitherlinkClueTest(4, 4, {
		"+ +-+ + +",
		" 2       ",
		"+ + + + +",
		"|        ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
	}, SolverStatus::NORMAL, 2001);

	SlitherlinkClueTest(4, 4, {
		"+-+ + + +",
		"|3       ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
	}, SolverStatus::NORMAL, 2002);

	SlitherlinkClueTest(4, 4, {
		"+x+x+-+ +",
		"x0x2|    ",
		"+x+-+x+ +",
		"x | x    ",
		"+x+ + + +",
		"x  3|    ",
		"+ +-+x+ +",
		"    x    ",
		"+ + + + +",
	}, SolverStatus::NORMAL, 2002);

	SlitherlinkDatabase::ReleaseDatabase();
}
}<commit_msg>Avoid conflict of test id<commit_after>#include <cassert>
#include <ctime>
#include <iostream>
#include <cstdlib>
#include <vector>

#include "../slitherlink/SlitherlinkDatabase.h"
#include "../slitherlink/SlitherlinkDatabaseMethod.hpp"
#include "../slitherlink/SlitherlinkField.h"
#include "../slitherlink/SlitherlinkProblem.h"
#include "Test.h"

namespace Penciloid
{
void PenciloidTest::SlitherlinkClueTest(int height, int width, std::vector<const char*> board, int expected_status, int test_id = -1)
{
	SlitherlinkField field;
	field.Init(height, width);

	for (int y = 0; y < height; ++y) {
		for (int x = 0; x < width; ++x) {
			char clue = board[y * 2 + 1][x * 2 + 1];
			if ('0' <= clue && clue <= '3') field.SetClue(y, x, clue - '0');
		}
	}

	field.CheckAll();

	bool is_status_ok = true;
	if (expected_status == SolverStatus::NORMAL && field.GetStatus() != expected_status) is_status_ok = false;
	if (expected_status == SolverStatus::SUCCESS && field.GetStatus() != expected_status) is_status_ok = false;
	if (expected_status == SolverStatus::INCONSISTENT && (field.GetStatus() & SolverStatus::INCONSISTENT) == 0) is_status_ok = false;

	if (!is_status_ok) {
		std::cerr << "SlitherlinkClueTest failed in test #" << test_id << std::endl;
		std::cerr << "expected: " << expected_status << ", actual: " << field.GetStatus() << " (field status)" << std::endl;
	}

	if (expected_status == SolverStatus::INCONSISTENT) return;

	for (int y = 0; y <= height * 2; ++y) {
		for (int x = 0; x <= width * 2; ++x) {
			if (y % 2 == x % 2) continue; // this is not a segment

			int expected =
				board[y][x] == ' ' ? SlitherlinkField::LOOP_UNDECIDED :
				board[y][x] == 'x' ? SlitherlinkField::LOOP_BLANK : SlitherlinkField::LOOP_LINE;

			if (field.GetSegmentStyle(y, x) != expected) {
				std::cerr << "SlitherlinkClueTest failed in test #" << test_id << std::endl;
				std::cerr << "expected: " << expected << ", actual: " << field.GetSegmentStyle(y, x) << " at (" << y << "," << x << ")" << std::endl;
				exit(1);
			}
		}
	}
}

bool PenciloidTest::SlitherlinkCheckGrid(SlitherlinkField &field, const int *expected)
{
	int height = field.GetHeight() * 2 + 1, width = field.GetWidth() * 2 + 1;

	for (int i = 0; i < height; ++i) {
		for (int j = 0; j < width; ++j) {
			if (i % 2 != j % 2) {
				int expected_style = (expected[i * width + j] == 1) ? SlitherlinkField::LOOP_LINE : SlitherlinkField::LOOP_BLANK;
				if (field.GetSegmentStyle(i, j) != expected_style) return false;
			}
		}
	}

	return true;
}

void PenciloidTest::SlitherlinkFieldTestByProblems()
{
	for (int t = 0; t < 2; ++t) {
		// t: enable database or not
		// t is specified in test_id by adding t * 1000

		if (t == 0) {
			if (SlitherlinkDatabase::IsCreated()) SlitherlinkDatabase::ReleaseDatabase();
		} else if (t == 1) {
			if (!SlitherlinkDatabase::IsCreated()) SlitherlinkDatabase::CreateDatabase();
		}

		SlitherlinkClueTest(3, 3, {
			"+x+x+-+",
			"x0x2| |",
			"+x+-+x+",
			"x | x |",
			"+-+x+x+",
			"|3x1x |",
			"+-+-+-+",
		}, SolverStatus::SUCCESS, t * 1000 + 0);

		SlitherlinkClueTest(3, 3, {
			"+-+-+-+",
			"| x x |",
			"+x+-+x+",
			"|3|3| |",
			"+-+x+x+",
			"x x |3|",
			"+x+x+-+",
		}, SolverStatus::SUCCESS, t * 1000 + 1);

		// 2: closed loop test
		SlitherlinkClueTest(5, 3, {
			"+-+x+-+",
			"|3|3|3|",
			"+x+-+x+",
			"|2x2x2|",
			"+-+-+-+",
			"x x1x x",
			"+x+x+x+",
			"x x x x",
			"+x+x+x+",
			"x x x x",
			"+x+x+x+",
		}, SolverStatus::SUCCESS, t * 1000 + 2);

		// 3: closed loop (inconsistent) test
		SlitherlinkClueTest(5, 3, {
			"+ + + +",
			" 3 3 3 ",
			"+ + + +",
			" 2 2 2 ",
			"+ + + +",
			"       ",
			"+ + + +",
			"     2 ",
			"+ + + +",
			"       ",
			"+ + + +",
		}, SolverStatus::INCONSISTENT, t * 1000 + 3);

		// 1xx: diagonal chain test
		SlitherlinkClueTest(4, 4, {
			"+x+x+ + +",
			"x0x      ",
			"+x+ + + +",
			"x  2     ",
			"+ + +x+ +",
			"    x1   ",
			"+ + + + +",
			"         ",
			"+ + + + +",
		}, SolverStatus::NORMAL, t * 1000 + 100);

		SlitherlinkClueTest(4, 4, {
			"+x+x+ + +",
			"x0x      ",
			"+x+-+ + +",
			"x |2x    ",
			"+ +x+-+ +",
			"    |3   ",
			"+ + + + +",
			"         ",
			"+ + + + +",
		}, SolverStatus::NORMAL, t * 1000 + 101);

		if (t == 1) SlitherlinkDatabase::ReleaseDatabase();
	}
}

void PenciloidTest::SlitherlinkReducedDatabaseTest()
{
	if (SlitherlinkDatabase::IsCreated()) SlitherlinkDatabase::ReleaseDatabase();
	SlitherlinkDatabase::CreateReducedDatabase(SlitherlinkDatabaseMethod());

	SlitherlinkClueTest(4, 4, {
		"+x+ + + +",
		"x1       ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
	}, SolverStatus::NORMAL, 2000);

	SlitherlinkClueTest(4, 4, {
		"+ +-+ + +",
		" 2       ",
		"+ + + + +",
		"|        ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
	}, SolverStatus::NORMAL, 2001);

	SlitherlinkClueTest(4, 4, {
		"+-+ + + +",
		"|3       ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
		"         ",
		"+ + + + +",
	}, SolverStatus::NORMAL, 2002);

	SlitherlinkClueTest(4, 4, {
		"+x+x+-+ +",
		"x0x2|    ",
		"+x+-+x+ +",
		"x | x    ",
		"+x+ + + +",
		"x  3|    ",
		"+ +-+x+ +",
		"    x    ",
		"+ + + + +",
	}, SolverStatus::NORMAL, 2003);

	SlitherlinkDatabase::ReleaseDatabase();
}
}<|endoftext|>


<commit_before>// Copyright (C) 2015 Kenenth Benzie
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef JSON_HPP
#define JSON_HPP

#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>

namespace json {
// Enumerations
enum type {
  TYPE_OBJECT,
  TYPE_ARRAY,
  TYPE_NUMBER,
  TYPE_STRING,
  TYPE_BOOL,
  TYPE_NULL
};

// Forward declarations
class value;
typedef std::pair<const std::string, json::value> pair;

// API
json::value read(const std::string &string, bool diag_on = true);
std::string write(const json::value &value, const char *tab = "\t");

// Objects
class object {
 public:
  // Types
  typedef std::map<std::string, json::value>::iterator iterator;
  typedef std::map<std::string, json::value>::const_iterator const_iterator;

  // Constructors
  object();
  object(std::string key, json::value value);
  object(json::pair pair);
  template <typename Type>
  object(std::string key, Type value);
  object(std::initializer_list<json::pair> values);

  // Accessors
  void add(std::string key, json::value value);
  void add(json::pair pair);

  json::value *get(std::string key);
  const json::value *get(std::string key) const;

  iterator begin();
  const_iterator begin() const;
  iterator end();
  const_iterator end() const;

 private:
  std::map<std::string, json::value> mEntries;
};

class array {
 public:
  // Types
  typedef std::vector<json::value>::iterator iterator;
  typedef std::vector<json::value>::const_iterator const_iterator;

  // Constructors
  array(std::initializer_list<json::value> values);
  template <typename... Args>
  array(Args... args);

  // Accessors
  void append(json::value value);
  iterator begin();
  const_iterator begin() const;
  iterator end();
  const_iterator end() const;
  json::value &operator[](const size_t index);
  const json::value &operator[](const size_t index) const;
  json::value &at(const size_t index);
  const json::value &at(const size_t index) const;

  size_t size();
  size_t size() const;

 private:
  std::vector<json::value> mEntries;
};

class value {
 public:
  // Constructors
  value();  // NOTE: A null value
  value(json::object object);
  value(json::pair pair);
  value(json::array array);
  explicit value(int8_t number);
  explicit value(int16_t number);
  explicit value(int32_t number);
  explicit value(int64_t number);
  explicit value(uint8_t number);
  explicit value(uint16_t number);
  explicit value(uint32_t number);
  explicit value(uint64_t number);
  explicit value(float number);
  explicit value(double number);
  explicit value(const char *string);
  value(std::string string);
  explicit value(bool boolean);

  // Accessors
  json::type &type();
  const json::type &type() const;
  json::object &object();
  const json::object &object() const;
  json::array &array();
  const json::array &array() const;
  double &number();
  const double &number() const;
  std::string &string();
  const std::string &string() const;
  bool &boolean();
  const bool &boolean() const;

 private:
  struct store_base {
    virtual ~store_base() {}
  };

  template <typename Type>
  struct store : public store_base {
    store(Type value) : value(value) {}
    Type value;
  };

  json::type mType;
  std::shared_ptr<store_base> mStore;
};

// Implementations
inline object::object() {}
inline object::object(std::string key, json::value value) {
  mEntries[key] = value;
}
inline object::object(json::pair pair) { mEntries.insert(pair); }
template <typename Type>
inline object::object(std::string key, Type value) {
  mEntries[key] = value;
}
inline object::object(std::initializer_list<json::pair> pairs) {
  mEntries.insert(pairs);
}

inline void object::add(std::string key, json::value value) {
  mEntries[key] = value;
}
inline void object::add(json::pair pair) { mEntries.insert(pair); }
inline json::value *object::get(std::string key) {
  auto iter = mEntries.find(key);
  if (mEntries.end() == iter) {
    return nullptr;
  }
  return &iter->second;
}
inline const json::value *object::get(std::string key) const {
  auto iter = mEntries.find(key);
  if (mEntries.end() == iter) {
    return nullptr;
  }
  return &iter->second;
}
inline object::iterator object::begin() { return mEntries.begin(); }
inline object::const_iterator object::begin() const { return mEntries.begin(); }
inline object::iterator object::end() { return mEntries.end(); }
inline object::const_iterator object::end() const { return mEntries.end(); }

inline array::array(std::initializer_list<json::value> values)
    : mEntries(values) {}
template <typename... Args>
inline array::array(Args... args)
    : mEntries(args...) {}

inline void array::append(json::value value) { mEntries.push_back(value); }
inline array::iterator array::begin() { return mEntries.begin(); }
inline array::const_iterator array::begin() const { return mEntries.begin(); }
inline array::iterator array::end() { return mEntries.end(); }
inline array::const_iterator array::end() const { return mEntries.end(); }
inline json::value &array::operator[](const size_t index) {
  return mEntries[index];
}
inline const json::value &array::operator[](const size_t index) const {
  return mEntries[index];
}
inline json::value &array::at(const size_t index) { return mEntries.at(index); }
inline const json::value &array::at(const size_t index) const {
  return mEntries.at(index);
}
inline size_t array::size() { return mEntries.size(); }
inline size_t array::size() const { return mEntries.size(); }

inline value::value() : mType(TYPE_NULL), mStore(nullptr) {}
inline value::value(json::object object)
    : mType(TYPE_OBJECT),
      mStore(std::make_shared<store<json::object>>(object)) {}
inline value::value(json::pair pair)
    : mType(TYPE_OBJECT), mStore(std::make_shared<store<json::object>>(pair)) {}
inline value::value(json::array array)
    : mType(TYPE_ARRAY), mStore(std::make_shared<store<json::array>>(array)) {}
inline value::value(int8_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(int16_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(int32_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(int64_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(uint8_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(uint16_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(uint32_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(uint64_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(float number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(double number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(const char *string)
    : mType(TYPE_STRING),
      mStore(std::make_shared<store<std::string>>(string)) {}
inline value::value(std::string string)
    : mType(TYPE_STRING),
      mStore(std::make_shared<store<std::string>>(string)) {}
inline value::value(bool boolean)
    : mType(TYPE_BOOL), mStore(std::make_shared<store<bool>>(boolean)) {}

#define CAST(Type) static_cast<store<Type> *>(mStore.get())->value
inline json::type &value::type() { return mType; }
inline const json::type &value::type() const { return mType; }
inline json::object &value::object() { return CAST(json::object); }
inline const json::object &value::object() const { return CAST(json::object); }
inline json::array &value::array() { return CAST(json::array); }
inline const json::array &value::array() const { return CAST(json::array); }
inline double &value::number() { return CAST(double); }
inline const double &value::number() const { return CAST(double); }
inline std::string &value::string() { return CAST(std::string); }
inline const std::string &value::string() const { return CAST(std::string); }
inline bool &value::boolean() { return CAST(bool); }
inline const bool &value::boolean() const { return CAST(bool); }
#undef CAST
}

#endif
<commit_msg>Add object member helper to cast numbers<commit_after>// Copyright (C) 2015 Kenenth Benzie
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef JSON_HPP
#define JSON_HPP

#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>

namespace json {
// Enumerations
enum type {
  TYPE_OBJECT,
  TYPE_ARRAY,
  TYPE_NUMBER,
  TYPE_STRING,
  TYPE_BOOL,
  TYPE_NULL
};

// Forward declarations
class value;
typedef std::pair<const std::string, json::value> pair;

// API
json::value read(const std::string &string, bool diag_on = true);
std::string write(const json::value &value, const char *tab = "\t");

// Objects
class object {
 public:
  // Types
  typedef std::map<std::string, json::value>::iterator iterator;
  typedef std::map<std::string, json::value>::const_iterator const_iterator;

  // Constructors
  object();
  object(std::string key, json::value value);
  object(json::pair pair);
  template <typename Type>
  object(std::string key, Type value);
  object(std::initializer_list<json::pair> values);

  // Accessors
  void add(std::string key, json::value value);
  void add(json::pair pair);

  json::value *get(std::string key);
  const json::value *get(std::string key) const;

  iterator begin();
  const_iterator begin() const;
  iterator end();
  const_iterator end() const;

 private:
  std::map<std::string, json::value> mEntries;
};

class array {
 public:
  // Types
  typedef std::vector<json::value>::iterator iterator;
  typedef std::vector<json::value>::const_iterator const_iterator;

  // Constructors
  array(std::initializer_list<json::value> values);
  template <typename... Args>
  array(Args... args);

  // Accessors
  void append(json::value value);
  iterator begin();
  const_iterator begin() const;
  iterator end();
  const_iterator end() const;
  json::value &operator[](const size_t index);
  const json::value &operator[](const size_t index) const;
  json::value &at(const size_t index);
  const json::value &at(const size_t index) const;

  size_t size();
  size_t size() const;

 private:
  std::vector<json::value> mEntries;
};

class value {
 public:
  // Constructors
  value();  // NOTE: A null value
  value(json::object object);
  value(json::pair pair);
  value(json::array array);
  explicit value(int8_t number);
  explicit value(int16_t number);
  explicit value(int32_t number);
  explicit value(int64_t number);
  explicit value(uint8_t number);
  explicit value(uint16_t number);
  explicit value(uint32_t number);
  explicit value(uint64_t number);
  explicit value(float number);
  explicit value(double number);
  explicit value(const char *string);
  value(std::string string);
  explicit value(bool boolean);

  // Accessors
  json::type &type();
  const json::type &type() const;
  json::object &object();
  const json::object &object() const;
  json::array &array();
  const json::array &array() const;
  double &number();
  const double &number() const;
  template <typename Number>
  Number number();
  std::string &string();
  const std::string &string() const;
  bool &boolean();
  const bool &boolean() const;

 private:
  struct store_base {
    virtual ~store_base() {}
  };

  template <typename Type>
  struct store : public store_base {
    store(Type value) : value(value) {}
    Type value;
  };

  json::type mType;
  std::shared_ptr<store_base> mStore;
};

// Implementations
inline object::object() {}
inline object::object(std::string key, json::value value) {
  mEntries[key] = value;
}
inline object::object(json::pair pair) { mEntries.insert(pair); }
template <typename Type>
inline object::object(std::string key, Type value) {
  mEntries[key] = value;
}
inline object::object(std::initializer_list<json::pair> pairs) {
  mEntries.insert(pairs);
}

inline void object::add(std::string key, json::value value) {
  mEntries[key] = value;
}
inline void object::add(json::pair pair) { mEntries.insert(pair); }
inline json::value *object::get(std::string key) {
  auto iter = mEntries.find(key);
  if (mEntries.end() == iter) {
    return nullptr;
  }
  return &iter->second;
}
inline const json::value *object::get(std::string key) const {
  auto iter = mEntries.find(key);
  if (mEntries.end() == iter) {
    return nullptr;
  }
  return &iter->second;
}
inline object::iterator object::begin() { return mEntries.begin(); }
inline object::const_iterator object::begin() const { return mEntries.begin(); }
inline object::iterator object::end() { return mEntries.end(); }
inline object::const_iterator object::end() const { return mEntries.end(); }

inline array::array(std::initializer_list<json::value> values)
    : mEntries(values) {}
template <typename... Args>
inline array::array(Args... args)
    : mEntries(args...) {}

inline void array::append(json::value value) { mEntries.push_back(value); }
inline array::iterator array::begin() { return mEntries.begin(); }
inline array::const_iterator array::begin() const { return mEntries.begin(); }
inline array::iterator array::end() { return mEntries.end(); }
inline array::const_iterator array::end() const { return mEntries.end(); }
inline json::value &array::operator[](const size_t index) {
  return mEntries[index];
}
inline const json::value &array::operator[](const size_t index) const {
  return mEntries[index];
}
inline json::value &array::at(const size_t index) { return mEntries.at(index); }
inline const json::value &array::at(const size_t index) const {
  return mEntries.at(index);
}
inline size_t array::size() { return mEntries.size(); }
inline size_t array::size() const { return mEntries.size(); }

inline value::value() : mType(TYPE_NULL), mStore(nullptr) {}
inline value::value(json::object object)
    : mType(TYPE_OBJECT),
      mStore(std::make_shared<store<json::object>>(object)) {}
inline value::value(json::pair pair)
    : mType(TYPE_OBJECT), mStore(std::make_shared<store<json::object>>(pair)) {}
inline value::value(json::array array)
    : mType(TYPE_ARRAY), mStore(std::make_shared<store<json::array>>(array)) {}
inline value::value(int8_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(int16_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(int32_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(int64_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(uint8_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(uint16_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(uint32_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(uint64_t number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(float number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(double number)
    : mType(TYPE_NUMBER), mStore(std::make_shared<store<double>>(number)) {}
inline value::value(const char *string)
    : mType(TYPE_STRING),
      mStore(std::make_shared<store<std::string>>(string)) {}
inline value::value(std::string string)
    : mType(TYPE_STRING),
      mStore(std::make_shared<store<std::string>>(string)) {}
inline value::value(bool boolean)
    : mType(TYPE_BOOL), mStore(std::make_shared<store<bool>>(boolean)) {}

#define CAST(Type) static_cast<store<Type> *>(mStore.get())->value
inline json::type &value::type() { return mType; }
inline const json::type &value::type() const { return mType; }
inline json::object &value::object() { return CAST(json::object); }
inline const json::object &value::object() const { return CAST(json::object); }
inline json::array &value::array() { return CAST(json::array); }
inline const json::array &value::array() const { return CAST(json::array); }
inline double &value::number() { return CAST(double); }
inline const double &value::number() const { return CAST(double); }
template <typename Number>
Number value::number() {
  return CAST(Number);
}
inline std::string &value::string() { return CAST(std::string); }
inline const std::string &value::string() const { return CAST(std::string); }
inline bool &value::boolean() { return CAST(bool); }
inline const bool &value::boolean() const { return CAST(bool); }
#undef CAST
}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2010 The QXmpp developers
 *
 * Author:
 *	Manjeet Dahiya
 *
 * Source:
 *	http://code.google.com/p/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * 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.
 *
 * 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.
 *
 */

#include "vCardManager.h"
#include "QXmppClient.h"
#include "QXmppUtils.h"
#include "utils.h"
#include "QXmppVCardManager.h"
#include <QFile>
#include <QDir>
#include <QDomDocument>
#include <QTextStream>
#include <QCoreApplication>
#include <QDomDocument>

vCardManager::vCardManager(QXmppClient* client) : QObject(client),
                m_client(client)
{
}

void vCardManager::vCardReceived(const QXmppVCardIq& vcard)
{
    QString from = vcard.from();
    if(from.isEmpty() && m_client)
    {
        from = m_client->configuration().jidBare();
        m_selfFullName = vcard.fullName();
    }

    m_mapBareJidVcard[from] = vcard;

    saveToCache(from);

    emit vCardReadyToUse(from);
}

bool vCardManager::isVCardAvailable(const QString& bareJid)
{
    return m_mapBareJidVcard.contains(bareJid);
}

void vCardManager::requestVCard(const QString& bareJid)
{
    if(m_client)
        m_client->vCardManager().requestVCard(bareJid);
}

//TODO not a good way to handle
QXmppVCardIq& vCardManager::getVCard(const QString& bareJid)
{
    return m_mapBareJidVcard[bareJid];
}

void vCardManager::saveToCache(const QString& bareJid)
{
    QDir dir;
    if(!dir.exists(getSettingsDir(m_client->configuration().jidBare())))
        dir.mkpath(getSettingsDir(m_client->configuration().jidBare()));

    QDir dir2;
    if(!dir2.exists(getSettingsDir(m_client->configuration().jidBare())+ "vCards/"))
        dir2.mkpath(getSettingsDir(m_client->configuration().jidBare())+ "vCards/");

    foreach(QString bareJid, m_mapBareJidVcard.keys())
    {
        QString fileVCard = getSettingsDir(m_client->configuration().jidBare()) + "vCards/" + bareJid + ".xml";
        QFile file(fileVCard);

        if(file.open(QIODevice::ReadWrite))
        {
            QXmlStreamWriter stream(&file);
            m_mapBareJidVcard[bareJid].toXml(&stream);
            file.close();
        }
    }
}

void vCardManager::loadAllFromCache()
{
    QDir dirVCards(getSettingsDir(m_client->configuration().jidBare())+ "vCards/");
    if(dirVCards.exists())
    {
        QStringList list = dirVCards.entryList(QStringList("*.xml"));
        foreach(QString fileName, list)
        {
            QFile file(getSettingsDir(m_client->configuration().jidBare())+ "vCards/" + fileName);
            QString bareJid = fileName;
            bareJid.chop(4);
            if(file.open(QIODevice::ReadOnly))
            {
                QDomDocument doc;
                if(doc.setContent(&file, true))
                {
                    QXmppVCardIq vCardIq;
                    vCardIq.parse(doc.documentElement());
                    m_mapBareJidVcard[bareJid] = vCardIq;
                    QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
                }
            }
        }
    }
}

QString vCardManager::getSelfFullName()
{
    return m_selfFullName;
}

// this should return scaled image
QImage vCardManager::getAvatar(const QString& bareJid) const
{
    if(m_mapBareJidVcard.contains(bareJid))
        return getImageFromByteArray(m_mapBareJidVcard[bareJid].photo());
    else
        return QImage();
}
<commit_msg>clear vcards map on startup<commit_after>/*
 * Copyright (C) 2008-2010 The QXmpp developers
 *
 * Author:
 *	Manjeet Dahiya
 *
 * Source:
 *	http://code.google.com/p/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * 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.
 *
 * 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.
 *
 */

#include "vCardManager.h"
#include "QXmppClient.h"
#include "QXmppUtils.h"
#include "utils.h"
#include "QXmppVCardManager.h"
#include <QFile>
#include <QDir>
#include <QDomDocument>
#include <QTextStream>
#include <QCoreApplication>
#include <QDomDocument>

vCardManager::vCardManager(QXmppClient* client) : QObject(client),
                m_client(client)
{
}

void vCardManager::vCardReceived(const QXmppVCardIq& vcard)
{
    QString from = vcard.from();
    if(from.isEmpty() && m_client)
    {
        from = m_client->configuration().jidBare();
        m_selfFullName = vcard.fullName();
    }

    m_mapBareJidVcard[from] = vcard;

    saveToCache(from);

    emit vCardReadyToUse(from);
}

bool vCardManager::isVCardAvailable(const QString& bareJid)
{
    return m_mapBareJidVcard.contains(bareJid);
}

void vCardManager::requestVCard(const QString& bareJid)
{
    if(m_client)
        m_client->vCardManager().requestVCard(bareJid);
}

//TODO not a good way to handle
QXmppVCardIq& vCardManager::getVCard(const QString& bareJid)
{
    return m_mapBareJidVcard[bareJid];
}

void vCardManager::saveToCache(const QString& bareJid)
{
    QDir dir;
    if(!dir.exists(getSettingsDir(m_client->configuration().jidBare())))
        dir.mkpath(getSettingsDir(m_client->configuration().jidBare()));

    QDir dir2;
    if(!dir2.exists(getSettingsDir(m_client->configuration().jidBare())+ "vCards/"))
        dir2.mkpath(getSettingsDir(m_client->configuration().jidBare())+ "vCards/");

    foreach(QString bareJid, m_mapBareJidVcard.keys())
    {
        QString fileVCard = getSettingsDir(m_client->configuration().jidBare()) + "vCards/" + bareJid + ".xml";
        QFile file(fileVCard);

        if(file.open(QIODevice::ReadWrite))
        {
            QXmlStreamWriter stream(&file);
            m_mapBareJidVcard[bareJid].toXml(&stream);
            file.close();
        }
    }
}

void vCardManager::loadAllFromCache()
{
    m_mapBareJidVcard.clear();

    QDir dirVCards(getSettingsDir(m_client->configuration().jidBare())+ "vCards/");
    if(dirVCards.exists())
    {
        QStringList list = dirVCards.entryList(QStringList("*.xml"));
        foreach(QString fileName, list)
        {
            QFile file(getSettingsDir(m_client->configuration().jidBare())+ "vCards/" + fileName);
            QString bareJid = fileName;
            bareJid.chop(4);
            if(file.open(QIODevice::ReadOnly))
            {
                QDomDocument doc;
                if(doc.setContent(&file, true))
                {
                    QXmppVCardIq vCardIq;
                    vCardIq.parse(doc.documentElement());
                    m_mapBareJidVcard[bareJid] = vCardIq;
                    QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
                }
            }
        }
    }
}

QString vCardManager::getSelfFullName()
{
    return m_selfFullName;
}

// this should return scaled image
QImage vCardManager::getAvatar(const QString& bareJid) const
{
    if(m_mapBareJidVcard.contains(bareJid))
        return getImageFromByteArray(m_mapBareJidVcard[bareJid].photo());
    else
        return QImage();
}
<|endoftext|>