<commit_before>/*
 * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program 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 Affero General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "StartProcess.h"
#include "Errors.h"
#include "Log.h"
#include "Optional.h"
#include "Util.h"
#include <boost/algorithm/string/join.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/process/args.hpp>
#include <boost/process/child.hpp>
#include <boost/process/env.hpp>
#include <boost/process/exe.hpp>
#include <boost/process/io.hpp>
#include <boost/process/pipe.hpp>
#include <boost/process/search_path.hpp>
#include <filesystem>

using namespace boost::process;
using namespace boost::iostreams;

namespace Acore
{
    template<typename T>
    class ACLogSink
    {
        T callback_;

    public:
        typedef char      char_type;
        typedef sink_tag  category;

        // Requires a callback type which has a void(std::string) signature
        ACLogSink(T callback)
            : callback_(std::move(callback)) { }

        std::streamsize write(char const* str, std::streamsize size)
        {
            std::string consoleStr(str, size);
            std::string utf8;
            if (consoleToUtf8(consoleStr, utf8))
                callback_(utf8);
            return size;
        }
    };

    template<typename T>
    auto MakeACLogSink(T&& callback)
        -> ACLogSink<typename std::decay<T>::type>
    {
        return { std::forward<T>(callback) };
    }

    template<typename T>
    static int CreateChildProcess(T waiter, std::string const& executable,
        std::vector<std::string> const& argsVector,
        std::string const& logger, std::string const& input,
        bool secure)
    {
        ipstream outStream;
        ipstream errStream;

        if (!secure)
        {
            LOG_TRACE(logger, "Starting process \"{}\" with arguments: \"{}\".",
                executable, boost::algorithm::join(argsVector, " "));
        }

        // prepare file with only read permission (boost process opens with read_write)
        std::shared_ptr<FILE> inputFile(!input.empty() ? fopen(input.c_str(), "rb") : nullptr, [](FILE* ptr)
        {
            if (ptr != nullptr)
                fclose(ptr);
        });

        // Start the child process
        child c = [&]()
        {
            if (inputFile)
            {
                // With binding stdin
                return child{
                    exe = std::filesystem::absolute(executable).string(),
                    args = argsVector,
                    env = environment(boost::this_process::environment()),
                    std_in = inputFile.get(),
                    std_out = outStream,
                    std_err = errStream
                };
            }
            else
            {
                // Without binding stdin
                return child{
                    exe = std::filesystem::absolute(executable).string(),
                    args = argsVector,
                    env = environment(boost::this_process::environment()),
                    std_in = boost::process::close,
                    std_out = outStream,
                    std_err = errStream
                };
            }
        }();

        auto outInfo = MakeACLogSink([&](std::string const& msg)
        {
            LOG_INFO(logger, "{}", msg);
        });

        auto outError = MakeACLogSink([&](std::string const& msg)
        {
            LOG_ERROR(logger, "{}", msg);
        });

        copy(outStream, outInfo);
        copy(errStream, outError);

        // Call the waiter in the current scope to prevent
        // the streams from closing too early on leaving the scope.
        int const result = waiter(c);

        if (!secure)
        {
            LOG_TRACE(logger, ">> Process \"{}\" finished with return value {}.",
                executable, result);
        }

        return result;
    }

    int StartProcess(std::string const& executable, std::vector<std::string> const& args,
        std::string const& logger, std::string input_file, bool secure)
    {
        return CreateChildProcess([](child& c) -> int
        {
            try
            {
                c.wait();
                return c.exit_code();
            }
            catch (...)
            {
                return EXIT_FAILURE;
            }
        }, executable, args, logger, input_file, secure);
    }

    class AsyncProcessResultImplementation
        : public AsyncProcessResult
    {
        std::string const executable;
        std::vector<std::string> const args;
        std::string const logger;
        std::string const input_file;
        bool const is_secure;

        std::atomic<bool> was_terminated;

        // Workaround for missing move support in boost < 1.57
        Optional<std::shared_ptr<std::future<int>>> result;
        Optional<std::reference_wrapper<child>> my_child;

    public:
        explicit AsyncProcessResultImplementation(std::string executable_, std::vector<std::string> args_,
            std::string logger_, std::string input_file_,
            bool secure)
            : executable(std::move(executable_)), args(std::move(args_)),
            logger(std::move(logger_)), input_file(input_file_),
            is_secure(secure), was_terminated(false) { }

        AsyncProcessResultImplementation(AsyncProcessResultImplementation const&) = delete;
        AsyncProcessResultImplementation& operator= (AsyncProcessResultImplementation const&) = delete;
        AsyncProcessResultImplementation(AsyncProcessResultImplementation&&) = delete;
        AsyncProcessResultImplementation& operator= (AsyncProcessResultImplementation&&) = delete;

        int StartProcess()
        {
            ASSERT(!my_child, "Process started already!");

            return CreateChildProcess([&](child& c) -> int
            {
                int exitCode;
                my_child = std::reference_wrapper<child>(c);

                try
                {
                    c.wait();
                    exitCode = c.exit_code();
                }
                catch (...)
                {
                    exitCode = EXIT_FAILURE;
                }

                my_child.reset();
                return was_terminated ? EXIT_FAILURE : exitCode;

            }, executable, args, logger, input_file, is_secure);
        }

        void SetFuture(std::future<int> result_)
        {
            result = std::make_shared<std::future<int>>(std::move(result_));
        }

        /// Returns the future which contains the result of the process
        /// as soon it is finished.
        std::future<int>& GetFutureResult() override
        {
            ASSERT(*result, "The process wasn't started!");
            return **result;
        }

        /// Tries to terminate the process
        void Terminate() override
        {
            if (my_child)
            {
                was_terminated = true;
                try
                {
                    my_child->get().terminate();
                }
                catch (...)
                {
                    // Do nothing
                }
            }
        }
    };

    std::shared_ptr<AsyncProcessResult>
        StartAsyncProcess(std::string executable, std::vector<std::string> args,
            std::string logger, std::string input_file, bool secure)
    {
        auto handle = std::make_shared<AsyncProcessResultImplementation>(
            std::move(executable), std::move(args), std::move(logger), std::move(input_file), secure);

        handle->SetFuture(std::async(std::launch::async, [handle] { return handle->StartProcess(); }));
        return handle;
    }

    std::string SearchExecutableInPath(std::string const& filename)
    {
        try
        {
            return search_path(filename).string();
        }
        catch (...)
        {
            return "";
        }
    }

} // namespace Acore
<commit_msg>fix(Core/Misc): Remove invalid comment (#10523)<commit_after>/*
 * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program 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 Affero General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "StartProcess.h"
#include "Errors.h"
#include "Log.h"
#include "Optional.h"
#include "Util.h"
#include <boost/algorithm/string/join.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/process/args.hpp>
#include <boost/process/child.hpp>
#include <boost/process/env.hpp>
#include <boost/process/exe.hpp>
#include <boost/process/io.hpp>
#include <boost/process/pipe.hpp>
#include <boost/process/search_path.hpp>
#include <filesystem>

using namespace boost::process;
using namespace boost::iostreams;

namespace Acore
{
    template<typename T>
    class ACLogSink
    {
        T callback_;

    public:
        typedef char      char_type;
        typedef sink_tag  category;

        // Requires a callback type which has a void(std::string) signature
        ACLogSink(T callback)
            : callback_(std::move(callback)) { }

        std::streamsize write(char const* str, std::streamsize size)
        {
            std::string consoleStr(str, size);
            std::string utf8;
            if (consoleToUtf8(consoleStr, utf8))
                callback_(utf8);
            return size;
        }
    };

    template<typename T>
    auto MakeACLogSink(T&& callback)
        -> ACLogSink<typename std::decay<T>::type>
    {
        return { std::forward<T>(callback) };
    }

    template<typename T>
    static int CreateChildProcess(T waiter, std::string const& executable,
        std::vector<std::string> const& argsVector,
        std::string const& logger, std::string const& input,
        bool secure)
    {
        ipstream outStream;
        ipstream errStream;

        if (!secure)
        {
            LOG_TRACE(logger, "Starting process \"{}\" with arguments: \"{}\".",
                executable, boost::algorithm::join(argsVector, " "));
        }

        // prepare file with only read permission (boost process opens with read_write)
        std::shared_ptr<FILE> inputFile(!input.empty() ? fopen(input.c_str(), "rb") : nullptr, [](FILE* ptr)
        {
            if (ptr != nullptr)
                fclose(ptr);
        });

        // Start the child process
        child c = [&]()
        {
            if (inputFile)
            {
                // With binding stdin
                return child{
                    exe = std::filesystem::absolute(executable).string(),
                    args = argsVector,
                    env = environment(boost::this_process::environment()),
                    std_in = inputFile.get(),
                    std_out = outStream,
                    std_err = errStream
                };
            }
            else
            {
                // Without binding stdin
                return child{
                    exe = std::filesystem::absolute(executable).string(),
                    args = argsVector,
                    env = environment(boost::this_process::environment()),
                    std_in = boost::process::close,
                    std_out = outStream,
                    std_err = errStream
                };
            }
        }();

        auto outInfo = MakeACLogSink([&](std::string const& msg)
        {
            LOG_INFO(logger, "{}", msg);
        });

        auto outError = MakeACLogSink([&](std::string const& msg)
        {
            LOG_ERROR(logger, "{}", msg);
        });

        copy(outStream, outInfo);
        copy(errStream, outError);

        // Call the waiter in the current scope to prevent
        // the streams from closing too early on leaving the scope.
        int const result = waiter(c);

        if (!secure)
        {
            LOG_TRACE(logger, ">> Process \"{}\" finished with return value {}.",
                executable, result);
        }

        return result;
    }

    int StartProcess(std::string const& executable, std::vector<std::string> const& args,
        std::string const& logger, std::string input_file, bool secure)
    {
        return CreateChildProcess([](child& c) -> int
        {
            try
            {
                c.wait();
                return c.exit_code();
            }
            catch (...)
            {
                return EXIT_FAILURE;
            }
        }, executable, args, logger, input_file, secure);
    }

    class AsyncProcessResultImplementation
        : public AsyncProcessResult
    {
        std::string const executable;
        std::vector<std::string> const args;
        std::string const logger;
        std::string const input_file;
        bool const is_secure;

        std::atomic<bool> was_terminated;

        Optional<std::shared_ptr<std::future<int>>> result;
        Optional<std::reference_wrapper<child>> my_child;

    public:
        explicit AsyncProcessResultImplementation(std::string executable_, std::vector<std::string> args_,
            std::string logger_, std::string input_file_,
            bool secure)
            : executable(std::move(executable_)), args(std::move(args_)),
            logger(std::move(logger_)), input_file(input_file_),
            is_secure(secure), was_terminated(false) { }

        AsyncProcessResultImplementation(AsyncProcessResultImplementation const&) = delete;
        AsyncProcessResultImplementation& operator= (AsyncProcessResultImplementation const&) = delete;
        AsyncProcessResultImplementation(AsyncProcessResultImplementation&&) = delete;
        AsyncProcessResultImplementation& operator= (AsyncProcessResultImplementation&&) = delete;

        int StartProcess()
        {
            ASSERT(!my_child, "Process started already!");

            return CreateChildProcess([&](child& c) -> int
            {
                int exitCode;
                my_child = std::reference_wrapper<child>(c);

                try
                {
                    c.wait();
                    exitCode = c.exit_code();
                }
                catch (...)
                {
                    exitCode = EXIT_FAILURE;
                }

                my_child.reset();
                return was_terminated ? EXIT_FAILURE : exitCode;

            }, executable, args, logger, input_file, is_secure);
        }

        void SetFuture(std::future<int> result_)
        {
            result = std::make_shared<std::future<int>>(std::move(result_));
        }

        /// Returns the future which contains the result of the process
        /// as soon it is finished.
        std::future<int>& GetFutureResult() override
        {
            ASSERT(*result, "The process wasn't started!");
            return **result;
        }

        /// Tries to terminate the process
        void Terminate() override
        {
            if (my_child)
            {
                was_terminated = true;
                try
                {
                    my_child->get().terminate();
                }
                catch (...)
                {
                    // Do nothing
                }
            }
        }
    };

    std::shared_ptr<AsyncProcessResult>
        StartAsyncProcess(std::string executable, std::vector<std::string> args,
            std::string logger, std::string input_file, bool secure)
    {
        auto handle = std::make_shared<AsyncProcessResultImplementation>(
            std::move(executable), std::move(args), std::move(logger), std::move(input_file), secure);

        handle->SetFuture(std::async(std::launch::async, [handle] { return handle->StartProcess(); }));
        return handle;
    }

    std::string SearchExecutableInPath(std::string const& filename)
    {
        try
        {
            return search_path(filename).string();
        }
        catch (...)
        {
            return "";
        }
    }

} // namespace Acore
<|endoftext|>


<commit_before>/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2011-2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnord-base/stringutil.h>
#include <fnord-base/inspect.h>
#include <fnord-json/jsonoutputstream.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

namespace fnord {
namespace json {

JSONOutputStream::JSONOutputStream(
    std::shared_ptr<OutputStream> output_stream) :
    output_(output_stream) {
}

JSONOutputStream::JSONOutputStream(
    std::unique_ptr<OutputStream> output_stream) {
  output_.reset(output_stream.release());
}

void JSONOutputStream::write(const JSONObject& obj) {
  for (const auto& t : obj) {
    emplace_back(t.type, t.data);
  }
}

void JSONOutputStream::emplace_back(kTokenType token) {
  emplace_back(token, "");
}

void JSONOutputStream::emplace_back(const JSONToken& token) {
  emplace_back(token.type, token.data);
}

void JSONOutputStream::emplace_back(
    kTokenType token,
    const std::string& data) {

  switch (token) {
    case JSON_ARRAY_END:
      endArray();

      if (!stack_.empty()) {
        stack_.pop();
      }

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      return;

    case JSON_OBJECT_END:
      endObject();

      if (!stack_.empty()) {
        stack_.pop();
      }

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      return;

    default:
      break;

  }

  if (!stack_.empty() && stack_.top().second > 0) {
    switch (stack_.top().first) {
      case JSON_ARRAY_BEGIN:
        addComma();
        break;

      case JSON_OBJECT_BEGIN:
        (stack_.top().second % 2 == 0) ? addComma() : addColon();
        break;

      default:
        break;
    }
  }

  switch (token) {

    case JSON_ARRAY_BEGIN:
      beginArray();
      stack_.emplace(JSON_ARRAY_BEGIN, 0);
      break;

    case JSON_OBJECT_BEGIN:
      beginObject();
      stack_.emplace(JSON_OBJECT_BEGIN, 0);
      break;

    case JSON_STRING:
      addString(data);

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    case JSON_NUMBER:
      addString(data);

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    case JSON_TRUE:
      addTrue();

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    case JSON_FALSE:
      addFalse();

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    case JSON_NULL:
      addNull();

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    default:
      break;
  }
}

void JSONOutputStream::beginObject() {
  output_->printf("{");
}

void JSONOutputStream::endObject() {
  output_->printf("}");
}

void JSONOutputStream::addObjectEntry(const std::string& key) {
  output_->printf("\"%s\": ", escapeString(key).c_str());
}

void JSONOutputStream::addComma() {
  output_->printf(",");
}

void JSONOutputStream::addColon() {
  output_->printf(":");
}

void JSONOutputStream::addString(const std::string& string) {
  output_->write("\"");
  output_->write(escapeString(string));
  output_->write("\"");
}

void JSONOutputStream::addInteger(int64_t value) {
  output_->write(StringUtil::toString(value));
}

void JSONOutputStream::addNull() {
  output_->write("null");
}

void JSONOutputStream::addTrue() {
  output_->write("true");
}

void JSONOutputStream::addFalse() {
  output_->write("false");
}

void JSONOutputStream::addFloat(double value) {
  if (std::isnormal(value)) {
    output_->write(StringUtil::toString(value));
  } else {
    addNull();
  }
}

void JSONOutputStream::beginArray() {
  output_->printf("[");
}

void JSONOutputStream::endArray() {
  output_->printf("]");
}

/*
template <>
void JSONOutputStream::addValue(const std::string& value) {
  addString(value);
}

template <>
void JSONOutputStream::addValue(const int& value) {
  output_->write(StringUtil::toString(value));
}

template <>
void JSONOutputStream::addValue(const unsigned long& value) {
  output_->write(StringUtil::toString(value));
}

template <>
void JSONOutputStream::addValue(const unsigned long long& value) {
  output_->write(StringUtil::toString(value));
}

template <>
void JSONOutputStream::addValue(const double& value) {
  addFloat(value);
}

template <>
void JSONOutputStream::addValue(const bool& value) {
  value ? addTrue() : addFalse();
}

template <>
void JSONOutputStream::addValue(const std::nullptr_t& value) {
  addNull();
}
*/

std::string JSONOutputStream::escapeString(const std::string& string) const {
  std::string new_str;

  for (int i = 0; i < string.size(); ++i) {
    switch (string.at(i)) {
      case '"':
        new_str += "\\\"";
        break;
      case '\\':
        new_str += "\\\\";
        break;
      case '\n':
        new_str += "\\n";
        break;
      case '\t':
        new_str += "\\t";
        break;
      default:
        new_str += string.at(i);
    }
  }

  return new_str;
}

} // namespace json
} // namespace fnord

<commit_msg>include fix<commit_after>/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2011-2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnord-base/stringutil.h>
#include <fnord-base/inspect.h>
#include <fnord-json/jsonoutputstream.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <cmath>

namespace fnord {
namespace json {

JSONOutputStream::JSONOutputStream(
    std::shared_ptr<OutputStream> output_stream) :
    output_(output_stream) {
}

JSONOutputStream::JSONOutputStream(
    std::unique_ptr<OutputStream> output_stream) {
  output_.reset(output_stream.release());
}

void JSONOutputStream::write(const JSONObject& obj) {
  for (const auto& t : obj) {
    emplace_back(t.type, t.data);
  }
}

void JSONOutputStream::emplace_back(kTokenType token) {
  emplace_back(token, "");
}

void JSONOutputStream::emplace_back(const JSONToken& token) {
  emplace_back(token.type, token.data);
}

void JSONOutputStream::emplace_back(
    kTokenType token,
    const std::string& data) {

  switch (token) {
    case JSON_ARRAY_END:
      endArray();

      if (!stack_.empty()) {
        stack_.pop();
      }

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      return;

    case JSON_OBJECT_END:
      endObject();

      if (!stack_.empty()) {
        stack_.pop();
      }

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      return;

    default:
      break;

  }

  if (!stack_.empty() && stack_.top().second > 0) {
    switch (stack_.top().first) {
      case JSON_ARRAY_BEGIN:
        addComma();
        break;

      case JSON_OBJECT_BEGIN:
        (stack_.top().second % 2 == 0) ? addComma() : addColon();
        break;

      default:
        break;
    }
  }

  switch (token) {

    case JSON_ARRAY_BEGIN:
      beginArray();
      stack_.emplace(JSON_ARRAY_BEGIN, 0);
      break;

    case JSON_OBJECT_BEGIN:
      beginObject();
      stack_.emplace(JSON_OBJECT_BEGIN, 0);
      break;

    case JSON_STRING:
      addString(data);

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    case JSON_NUMBER:
      addString(data);

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    case JSON_TRUE:
      addTrue();

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    case JSON_FALSE:
      addFalse();

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    case JSON_NULL:
      addNull();

      if (!stack_.empty()) {
        stack_.top().second++;
      }
      break;

    default:
      break;
  }
}

void JSONOutputStream::beginObject() {
  output_->printf("{");
}

void JSONOutputStream::endObject() {
  output_->printf("}");
}

void JSONOutputStream::addObjectEntry(const std::string& key) {
  output_->printf("\"%s\": ", escapeString(key).c_str());
}

void JSONOutputStream::addComma() {
  output_->printf(",");
}

void JSONOutputStream::addColon() {
  output_->printf(":");
}

void JSONOutputStream::addString(const std::string& string) {
  output_->write("\"");
  output_->write(escapeString(string));
  output_->write("\"");
}

void JSONOutputStream::addInteger(int64_t value) {
  output_->write(StringUtil::toString(value));
}

void JSONOutputStream::addNull() {
  output_->write("null");
}

void JSONOutputStream::addTrue() {
  output_->write("true");
}

void JSONOutputStream::addFalse() {
  output_->write("false");
}

void JSONOutputStream::addFloat(double value) {
  if (std::isnormal(value)) {
    output_->write(StringUtil::toString(value));
  } else {
    addNull();
  }
}

void JSONOutputStream::beginArray() {
  output_->printf("[");
}

void JSONOutputStream::endArray() {
  output_->printf("]");
}

/*
template <>
void JSONOutputStream::addValue(const std::string& value) {
  addString(value);
}

template <>
void JSONOutputStream::addValue(const int& value) {
  output_->write(StringUtil::toString(value));
}

template <>
void JSONOutputStream::addValue(const unsigned long& value) {
  output_->write(StringUtil::toString(value));
}

template <>
void JSONOutputStream::addValue(const unsigned long long& value) {
  output_->write(StringUtil::toString(value));
}

template <>
void JSONOutputStream::addValue(const double& value) {
  addFloat(value);
}

template <>
void JSONOutputStream::addValue(const bool& value) {
  value ? addTrue() : addFalse();
}

template <>
void JSONOutputStream::addValue(const std::nullptr_t& value) {
  addNull();
}
*/

std::string JSONOutputStream::escapeString(const std::string& string) const {
  std::string new_str;

  for (int i = 0; i < string.size(); ++i) {
    switch (string.at(i)) {
      case '"':
        new_str += "\\\"";
        break;
      case '\\':
        new_str += "\\\\";
        break;
      case '\n':
        new_str += "\\n";
        break;
      case '\t':
        new_str += "\\t";
        break;
      default:
        new_str += string.at(i);
    }
  }

  return new_str;
}

} // namespace json
} // namespace fnord

<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2015 The Android Open Source Project
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Template class that is either type of Left or Right.
 *//*--------------------------------------------------------------------*/

#include "tcuEither.hpp"

namespace tcu
{
namespace
{

enum
{
	COPYCHECK_VALUE = 1637423219
};

class TestClassWithConstructor
{
public:
	TestClassWithConstructor (int i)
		: m_i			(i)
		, m_copyCheck	(COPYCHECK_VALUE)
	{
	}

	~TestClassWithConstructor (void)
	{
		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);
	}

	TestClassWithConstructor (const TestClassWithConstructor& other)
		: m_i			(other.m_i)
		, m_copyCheck	(other.m_copyCheck)
	{
	}

	TestClassWithConstructor& operator= (const TestClassWithConstructor& other)
	{
		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);

		if (this == &other)
			return *this;

		m_i = other.m_i;
		m_copyCheck = other.m_copyCheck;

		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);

		return *this;
	}

	int getValue (void) const
	{
		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);

		return m_i;
	}

private:
	int m_i;
	int m_copyCheck;
};

} // anonymous

void Either_selfTest (void)
{
	// Simple test for first
	{
		const int					intValue	= 1503457782;
		const Either<int, float>	either		(intValue);

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<int>());
		TCU_CHECK(!either.is<float>());

		TCU_CHECK(either.getFirst() == intValue);
		TCU_CHECK(either.get<int>() == intValue);
	}

	// Simple test for second
	{
		const float					floatValue	= 0.43223332995f;
		const Either<int, float>	either		(floatValue);

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(!either.is<int>());
		TCU_CHECK(either.is<float>());

		TCU_CHECK(either.getSecond() == floatValue);
		TCU_CHECK(either.get<float>() == floatValue);
	}

	// Assign first value
	{
		const int			intValue	= 1942092699;
		const float			floatValue	= 0.43223332995f;
		Either<int, float>	either		(floatValue);

		either = intValue;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<int>());
		TCU_CHECK(!either.is<float>());

		TCU_CHECK(either.getFirst() == intValue);
		TCU_CHECK(either.get<int>() == intValue);
	}

	// Assign second value
	{
		const int			intValue	= 1942092699;
		const float			floatValue	= 0.43223332995f;
		Either<int, float>	either		(intValue);

		either = floatValue;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(!either.is<int>());
		TCU_CHECK(either.is<float>());

		TCU_CHECK(either.getSecond() == floatValue);
		TCU_CHECK(either.get<float>() == floatValue);
	}

	// Assign first either value
	{
		const int					intValue	= 1942092699;
		const float					floatValue	= 0.43223332995f;
		Either<int, float>			either		(floatValue);
		const Either<int, float>	otherEither	(intValue);

		either = otherEither;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<int>());
		TCU_CHECK(!either.is<float>());

		TCU_CHECK(either.getFirst() == intValue);
		TCU_CHECK(either.get<int>() == intValue);
	}

	// Assign second either value
	{
		const int					intValue	= 1942092699;
		const float					floatValue	= 0.43223332995f;
		Either<int, float>			either		(intValue);
		const Either<int, float>	otherEither	(floatValue);

		either = otherEither;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(!either.is<int>());
		TCU_CHECK(either.is<float>());

		TCU_CHECK(either.getSecond() == floatValue);
		TCU_CHECK(either.get<float>() == floatValue);
	}

	// Simple test for first with constructor
	{
		const TestClassWithConstructor				testObject	(171899615);
		const Either<TestClassWithConstructor, int>	either		(testObject);

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getFirst().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Simple test for second with constructor
	{
		const TestClassWithConstructor				testObject	(171899615);
		const Either<int, TestClassWithConstructor>	either		(testObject);

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getSecond().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign first with constructor
	{
		const int								intValue	= 1942092699;
		const TestClassWithConstructor			testObject	(171899615);
		Either<TestClassWithConstructor, int>	either		(intValue);

		either = testObject;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getFirst().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign second with constructor
	{
		const int								intValue	= 1942092699;
		const TestClassWithConstructor			testObject	(171899615);
		Either<int, TestClassWithConstructor>	either		(intValue);

		either = testObject;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getSecond().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign first either with constructor
	{
		const int									intValue	= 1942092699;
		const TestClassWithConstructor				testObject	(171899615);
		Either<TestClassWithConstructor, int>		either		(intValue);
		const Either<TestClassWithConstructor, int>	otherEither	(testObject);

		either = otherEither;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getFirst().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign second either with constructor
	{
		const int									intValue	= 1942092699;
		const TestClassWithConstructor				testObject	(171899615);
		Either<int, TestClassWithConstructor>		either		(intValue);
		const Either<int, TestClassWithConstructor>	otherEither	(testObject);

		either = otherEither;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getSecond().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}
}

} // tcu
<commit_msg>Do not throw exception from destructior in tcu::Either tests<commit_after>/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2015 The Android Open Source Project
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Template class that is either type of Left or Right.
 *//*--------------------------------------------------------------------*/

#include "tcuEither.hpp"

namespace tcu
{
namespace
{

enum
{
	COPYCHECK_VALUE = 1637423219
};

class TestClassWithConstructor
{
public:
	TestClassWithConstructor (int i)
		: m_i			(i)
		, m_copyCheck	(COPYCHECK_VALUE)
	{
	}

	~TestClassWithConstructor (void)
	{
		DE_TEST_ASSERT(m_copyCheck == COPYCHECK_VALUE);
	}

	TestClassWithConstructor (const TestClassWithConstructor& other)
		: m_i			(other.m_i)
		, m_copyCheck	(other.m_copyCheck)
	{
	}

	TestClassWithConstructor& operator= (const TestClassWithConstructor& other)
	{
		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);

		if (this == &other)
			return *this;

		m_i = other.m_i;
		m_copyCheck = other.m_copyCheck;

		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);

		return *this;
	}

	int getValue (void) const
	{
		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);

		return m_i;
	}

private:
	int m_i;
	int m_copyCheck;
};

} // anonymous

void Either_selfTest (void)
{
	// Simple test for first
	{
		const int					intValue	= 1503457782;
		const Either<int, float>	either		(intValue);

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<int>());
		TCU_CHECK(!either.is<float>());

		TCU_CHECK(either.getFirst() == intValue);
		TCU_CHECK(either.get<int>() == intValue);
	}

	// Simple test for second
	{
		const float					floatValue	= 0.43223332995f;
		const Either<int, float>	either		(floatValue);

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(!either.is<int>());
		TCU_CHECK(either.is<float>());

		TCU_CHECK(either.getSecond() == floatValue);
		TCU_CHECK(either.get<float>() == floatValue);
	}

	// Assign first value
	{
		const int			intValue	= 1942092699;
		const float			floatValue	= 0.43223332995f;
		Either<int, float>	either		(floatValue);

		either = intValue;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<int>());
		TCU_CHECK(!either.is<float>());

		TCU_CHECK(either.getFirst() == intValue);
		TCU_CHECK(either.get<int>() == intValue);
	}

	// Assign second value
	{
		const int			intValue	= 1942092699;
		const float			floatValue	= 0.43223332995f;
		Either<int, float>	either		(intValue);

		either = floatValue;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(!either.is<int>());
		TCU_CHECK(either.is<float>());

		TCU_CHECK(either.getSecond() == floatValue);
		TCU_CHECK(either.get<float>() == floatValue);
	}

	// Assign first either value
	{
		const int					intValue	= 1942092699;
		const float					floatValue	= 0.43223332995f;
		Either<int, float>			either		(floatValue);
		const Either<int, float>	otherEither	(intValue);

		either = otherEither;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<int>());
		TCU_CHECK(!either.is<float>());

		TCU_CHECK(either.getFirst() == intValue);
		TCU_CHECK(either.get<int>() == intValue);
	}

	// Assign second either value
	{
		const int					intValue	= 1942092699;
		const float					floatValue	= 0.43223332995f;
		Either<int, float>			either		(intValue);
		const Either<int, float>	otherEither	(floatValue);

		either = otherEither;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(!either.is<int>());
		TCU_CHECK(either.is<float>());

		TCU_CHECK(either.getSecond() == floatValue);
		TCU_CHECK(either.get<float>() == floatValue);
	}

	// Simple test for first with constructor
	{
		const TestClassWithConstructor				testObject	(171899615);
		const Either<TestClassWithConstructor, int>	either		(testObject);

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getFirst().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Simple test for second with constructor
	{
		const TestClassWithConstructor				testObject	(171899615);
		const Either<int, TestClassWithConstructor>	either		(testObject);

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getSecond().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign first with constructor
	{
		const int								intValue	= 1942092699;
		const TestClassWithConstructor			testObject	(171899615);
		Either<TestClassWithConstructor, int>	either		(intValue);

		either = testObject;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getFirst().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign second with constructor
	{
		const int								intValue	= 1942092699;
		const TestClassWithConstructor			testObject	(171899615);
		Either<int, TestClassWithConstructor>	either		(intValue);

		either = testObject;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getSecond().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign first either with constructor
	{
		const int									intValue	= 1942092699;
		const TestClassWithConstructor				testObject	(171899615);
		Either<TestClassWithConstructor, int>		either		(intValue);
		const Either<TestClassWithConstructor, int>	otherEither	(testObject);

		either = otherEither;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getFirst().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign second either with constructor
	{
		const int									intValue	= 1942092699;
		const TestClassWithConstructor				testObject	(171899615);
		Either<int, TestClassWithConstructor>		either		(intValue);
		const Either<int, TestClassWithConstructor>	otherEither	(testObject);

		either = otherEither;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getSecond().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}
}

} // tcu
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file globals.hpp
 * \brief Contains some global functions.
*/

#pragma once

namespace etl {

/*!
 * \brief Indicates if the given expression is a square matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a square matrix, false otherwise.
 */
template<typename E>
bool is_square(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) == etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression is a rectangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a rectangular matrix, false otherwise.
 */
template<typename E>
bool is_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) != etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are square.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are square, false otherwise.
 */
template<typename E>
bool is_sub_square(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) == etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are rectangular.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are rectangular, false otherwise.
 */
template<typename E>
bool is_sub_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) != etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression is a symmetric matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a symmetric matrix, false otherwise.
 */
template<typename E>
bool is_symmetric(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i){
            for(std::size_t j = i + 1; j < etl::dim<0>(expr); ++j){
                if(expr(i, j) != expr(j, i)){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a lower triangular matrix, false otherwise.
 */
template<typename E>
bool is_lower_triangular(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i){
            for(std::size_t j = i + 1; j < etl::dim<0>(expr); ++j){
                if(expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly lower triangular matrix, false otherwise.
 */
template<typename E>
bool is_strictly_lower_triangular(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr); ++i){
            for(std::size_t j = i; j < etl::dim<0>(expr); ++j){
                if(expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a upper triangular matrix, false otherwise.
 */
template<typename E>
bool is_upper_triangular(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 1; i < etl::dim<0>(expr); ++i){
            for(std::size_t j = 0; j < i; ++j){
                if(expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly upper triangular matrix, false otherwise.
 */
template<typename E>
bool is_strictly_upper_triangular(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr); ++i){
            for(std::size_t j = 0; j <= i; ++j){
                if(expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a diagonal matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a diagonal matrix, false otherwise.
 */
template<typename E>
bool is_diagonal(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr); ++i){
            for(std::size_t j = 0; j <= etl::dim<0>(expr); ++j){
                if(i != j && expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is uniform (all elements of the same value)
 * \param expr The expression to test
 * \return true if the given expression is uniform, false otherwise.
 */
template<typename E>
bool is_uniform(E&& expr){
    if(!etl::size(expr)){
        return false;
    }

    auto first = *expr.begin();

    for(auto v : expr){
        if(v != first){
            return false;
        }
    }

    return true;
}

/*!
 * \brief Returns the trace of the given square matrix.
 *
 * If the given expression does not represent a square matrix, this function will fail
 *
 * \param expr The expression to get the trace from.
 * \return The trace of the given expression
 */
template<typename E>
value_t<E> trace(E&& expr){
    assert_square(expr);

    auto value = value_t<E>();

    for(std::size_t i = 0; i < etl::dim<0>(expr); ++i){
        value += expr(i, i);
    }

    return value;
}

} //end of namespace etl
<commit_msg>Fix is_diagonal<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file globals.hpp
 * \brief Contains some global functions.
*/

#pragma once

namespace etl {

/*!
 * \brief Indicates if the given expression is a square matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a square matrix, false otherwise.
 */
template<typename E>
bool is_square(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) == etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression is a rectangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a rectangular matrix, false otherwise.
 */
template<typename E>
bool is_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 2 && etl::dim<0>(expr) != etl::dim<1>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are square.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are square, false otherwise.
 */
template<typename E>
bool is_sub_square(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) == etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression contains sub matrices that are rectangular.
 * \param expr The expression to test
 * \return true if the given expression contains sub matrices that are rectangular, false otherwise.
 */
template<typename E>
bool is_sub_rectangular(E&& expr) {
    return decay_traits<E>::dimensions() == 3 && etl::dim<1>(expr) != etl::dim<2>(expr);
}

/*!
 * \brief Indicates if the given expression is a symmetric matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a symmetric matrix, false otherwise.
 */
template<typename E>
bool is_symmetric(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i){
            for(std::size_t j = i + 1; j < etl::dim<0>(expr); ++j){
                if(expr(i, j) != expr(j, i)){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a lower triangular matrix, false otherwise.
 */
template<typename E>
bool is_lower_triangular(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr) - 1; ++i){
            for(std::size_t j = i + 1; j < etl::dim<0>(expr); ++j){
                if(expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly lower triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly lower triangular matrix, false otherwise.
 */
template<typename E>
bool is_strictly_lower_triangular(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr); ++i){
            for(std::size_t j = i; j < etl::dim<0>(expr); ++j){
                if(expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a upper triangular matrix, false otherwise.
 */
template<typename E>
bool is_upper_triangular(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 1; i < etl::dim<0>(expr); ++i){
            for(std::size_t j = 0; j < i; ++j){
                if(expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a strictly upper triangular matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a strictly upper triangular matrix, false otherwise.
 */
template<typename E>
bool is_strictly_upper_triangular(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr); ++i){
            for(std::size_t j = 0; j <= i; ++j){
                if(expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is a diagonal matrix or not.
 * \param expr The expression to test
 * \return true if the given expression is a diagonal matrix, false otherwise.
 */
template<typename E>
bool is_diagonal(E&& expr) {
    if(is_square(expr)){
        for(std::size_t i = 0; i < etl::dim<0>(expr); ++i){
            for(std::size_t j = 0; j < etl::dim<0>(expr); ++j){
                if(i != j && expr(i, j) != 0.0){
                    return false;
                }
            }
        }

        return true;
    }

    return false;
}

/*!
 * \brief Indicates if the given expression is uniform (all elements of the same value)
 * \param expr The expression to test
 * \return true if the given expression is uniform, false otherwise.
 */
template<typename E>
bool is_uniform(E&& expr){
    if(!etl::size(expr)){
        return false;
    }

    auto first = *expr.begin();

    for(auto v : expr){
        if(v != first){
            return false;
        }
    }

    return true;
}

/*!
 * \brief Returns the trace of the given square matrix.
 *
 * If the given expression does not represent a square matrix, this function will fail
 *
 * \param expr The expression to get the trace from.
 * \return The trace of the given expression
 */
template<typename E>
value_t<E> trace(E&& expr){
    assert_square(expr);

    auto value = value_t<E>();

    for(std::size_t i = 0; i < etl::dim<0>(expr); ++i){
        value += expr(i, i);
    }

    return value;
}

} //end of namespace etl
<|endoftext|>


<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "TiledMesh.h"
#include "Parser.h"
#include "InputParameters.h"

// libMesh includes
#include "libmesh/mesh_modification.h"

template<>
InputParameters validParams<TiledMesh>()
{
  InputParameters params = validParams<MooseMesh>();

  params.addParam<Real>("x_width", 0, "The tile width in the x direction");
  params.addParam<Real>("y_width", 0, "The tile width in the y direction");
  params.addParam<Real>("z_width", 0, "The tile width in the z direction");

  params.addParam<BoundaryName>("left_boundary", "TODO");
  params.addParam<BoundaryName>("right_boundary", "TODO");
  params.addParam<BoundaryName>("top_boundary", "TODO");
  params.addParam<BoundaryName>("bottom_boundary", "TODO");
  params.addParam<BoundaryName>("front_boundary", "TODO");
  params.addParam<BoundaryName>("back_boundary", "TODO");

  params.addParam<unsigned int>("x_tiles", 1, "TODO");
  params.addParam<unsigned int>("y_tiles", 1, "TODO");
  params.addParam<unsigned int>("z_tiles", 1, "TODO");

  return params;
}

TiledMesh::TiledMesh(const std::string & name, InputParameters parameters):
    MooseMesh(name, parameters),
    _x_width(getParam<Real>("x_width")),
    _y_width(getParam<Real>("y_width")),
    _z_width(getParam<Real>("z_width"))
{

// This class only works with SerialMesh
#ifndef LIBMESH_ENABLE_PARMESH

  std::string mesh_file(getParam<MeshFileName>("file"));

  if (mesh_file.rfind(".exd") < mesh_file.size() ||
      mesh_file.rfind(".e") < mesh_file.size())
  {
    ExodusII_IO ex(*this);
    ex.read(mesh_file);
  }
  else
    read(mesh_file);

  BoundaryID left = getBoundaryID(getParam<BoundaryName>("left_boundary"));
  BoundaryID right = getBoundaryID(getParam<BoundaryName>("right_boundary"));
  BoundaryID top = getBoundaryID(getParam<BoundaryName>("top_boundary"));
  BoundaryID bottom = getBoundaryID(getParam<BoundaryName>("bottom_boundary"));
  BoundaryID front = getBoundaryID(getParam<BoundaryName>("front_boundary"));
  BoundaryID back = getBoundaryID(getParam<BoundaryName>("back_boundary"));

  {
    AutoPtr<MeshBase> clone = _mesh.clone();

    // Build X Tiles
    for (unsigned int i=1; i<getParam<unsigned int>("x_tiles"); ++i)
    {
      MeshTools::Modification::translate(*clone, _x_width, 0, 0);
      _mesh.stitch_meshes(dynamic_cast<SerialMesh &>(*clone), right, left, TOLERANCE, true);
    }
  }
  {
    AutoPtr<MeshBase> clone = _mesh.clone();

    // Build Y Tiles
    for (unsigned int i=1; i<getParam<unsigned int>("y_tiles"); ++i)
    {
      MeshTools::Modification::translate(*clone, 0, _y_width, 0);
      _mesh.stitch_meshes(dynamic_cast<SerialMesh &>(*clone), top, bottom, TOLERANCE, true);
    }
  }
  {
    AutoPtr<MeshBase> clone = _mesh.clone();

    // Build Y Tiles
    for (unsigned int i=1; i<getParam<unsigned int>("z_tiles"); ++i)
    {
      MeshTools::Modification::translate(*clone, 0, 0, _z_width);
      _mesh.stitch_meshes(dynamic_cast<SerialMesh &>(*clone), front, back, TOLERANCE, true);
    }
  }

#else
  mooseError("TiledMesh cannot be used with --enable-parmesh");
#endif

}
<commit_msg>Fixing debug error in TiledMesh - refs #1729<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "TiledMesh.h"
#include "Parser.h"
#include "InputParameters.h"

// libMesh includes
#include "libmesh/mesh_modification.h"

template<>
InputParameters validParams<TiledMesh>()
{
  InputParameters params = validParams<MooseMesh>();

  params.addParam<Real>("x_width", 0, "The tile width in the x direction");
  params.addParam<Real>("y_width", 0, "The tile width in the y direction");
  params.addParam<Real>("z_width", 0, "The tile width in the z direction");

  params.addParam<BoundaryName>("left_boundary", "TODO");
  params.addParam<BoundaryName>("right_boundary", "TODO");
  params.addParam<BoundaryName>("top_boundary", "TODO");
  params.addParam<BoundaryName>("bottom_boundary", "TODO");
  params.addParam<BoundaryName>("front_boundary", "TODO");
  params.addParam<BoundaryName>("back_boundary", "TODO");

  params.addParam<unsigned int>("x_tiles", 1, "TODO");
  params.addParam<unsigned int>("y_tiles", 1, "TODO");
  params.addParam<unsigned int>("z_tiles", 1, "TODO");

  return params;
}

TiledMesh::TiledMesh(const std::string & name, InputParameters parameters):
    MooseMesh(name, parameters),
    _x_width(getParam<Real>("x_width")),
    _y_width(getParam<Real>("y_width")),
    _z_width(getParam<Real>("z_width"))
{

// This class only works with SerialMesh
#ifndef LIBMESH_ENABLE_PARMESH

  std::string mesh_file(getParam<MeshFileName>("file"));

  if (mesh_file.rfind(".exd") < mesh_file.size() ||
      mesh_file.rfind(".e") < mesh_file.size())
  {
    ExodusII_IO ex(*this);
    ex.read(mesh_file);
    _mesh.prepare_for_use();
  }
  else
    read(mesh_file);

  BoundaryID left = getBoundaryID(getParam<BoundaryName>("left_boundary"));
  BoundaryID right = getBoundaryID(getParam<BoundaryName>("right_boundary"));
  BoundaryID top = getBoundaryID(getParam<BoundaryName>("top_boundary"));
  BoundaryID bottom = getBoundaryID(getParam<BoundaryName>("bottom_boundary"));
  BoundaryID front = getBoundaryID(getParam<BoundaryName>("front_boundary"));
  BoundaryID back = getBoundaryID(getParam<BoundaryName>("back_boundary"));

  {
    AutoPtr<MeshBase> clone = _mesh.clone();

    // Build X Tiles
    for (unsigned int i=1; i<getParam<unsigned int>("x_tiles"); ++i)
    {
      MeshTools::Modification::translate(*clone, _x_width, 0, 0);
      _mesh.stitch_meshes(dynamic_cast<SerialMesh &>(*clone), right, left, TOLERANCE, true);
    }
  }
  {
    AutoPtr<MeshBase> clone = _mesh.clone();

    // Build Y Tiles
    for (unsigned int i=1; i<getParam<unsigned int>("y_tiles"); ++i)
    {
      MeshTools::Modification::translate(*clone, 0, _y_width, 0);
      _mesh.stitch_meshes(dynamic_cast<SerialMesh &>(*clone), top, bottom, TOLERANCE, true);
    }
  }
  {
    AutoPtr<MeshBase> clone = _mesh.clone();

    // Build Y Tiles
    for (unsigned int i=1; i<getParam<unsigned int>("z_tiles"); ++i)
    {
      MeshTools::Modification::translate(*clone, 0, 0, _z_width);
      _mesh.stitch_meshes(dynamic_cast<SerialMesh &>(*clone), front, back, TOLERANCE, true);
    }
  }

#else
  mooseError("TiledMesh cannot be used with --enable-parmesh");
#endif

}
<|endoftext|>


<commit_before>#pragma once

#include <cstdint>
#include <cstddef>
#include <string>
#include "athena/DNA.hpp"

namespace hecl {

/**
 * @brief FourCC representation used within HECL's database
 *
 * FourCCs are efficient, mnemonic four-char-sequences used to represent types
 * while fitting comfortably in a 32-bit word. HECL uses a four-char array
 * to remain endian-independent.
 */
class FourCC {
protected:
  union {
    char fcc[4];
    uint32_t num;
  };

public:
  constexpr FourCC() /* Sentinel FourCC */
  : num(0) {}
  constexpr FourCC(const FourCC& other) : num(other.num) {}
  constexpr FourCC(const char* name) : num(*(uint32_t*)name) {}
  constexpr FourCC(uint32_t n) : num(n) {}
  bool operator==(const FourCC& other) const { return num == other.num; }
  bool operator!=(const FourCC& other) const { return num != other.num; }
  bool operator==(const char* other) const { return num == *(uint32_t*)other; }
  bool operator!=(const char* other) const { return num != *(uint32_t*)other; }
  bool operator==(int32_t other) const { return num == uint32_t(other); }
  bool operator!=(int32_t other) const { return num != uint32_t(other); }
  bool operator==(uint32_t other) const { return num == other; }
  bool operator!=(uint32_t other) const { return num != other; }
  std::string toString() const { return std::string(fcc, 4); }
  uint32_t toUint32() const { return num; }
  const char* getChars() const { return fcc; }
  char* getChars() { return fcc; }
  bool IsValid() const { return num != 0; }
};
#define FOURCC(chars) FourCC(SBIG(chars))

using BigDNA = athena::io::DNA<athena::Big>;

/** FourCC with DNA read/write */
class DNAFourCC final : public BigDNA, public FourCC {
public:
  DNAFourCC() : FourCC() {}
  DNAFourCC(const FourCC& other) : FourCC() { num = other.toUint32(); }
  DNAFourCC(const char* name) : FourCC(name) {}
  DNAFourCC(uint32_t n) : FourCC(n) {}
  AT_DECL_EXPLICIT_DNA_YAML
};
template <>
inline void DNAFourCC::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {
  r.readUBytesToBuf(fcc, 4);
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
  w.writeUBytes((atUint8*)fcc, 4);
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
  std::string rs = r.readString(nullptr);
  strncpy(fcc, rs.c_str(), 4);
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) {
  w.writeString(nullptr, std::string(fcc, 4));
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
  s += 4;
}

} // namespace hecl

namespace std {
template <>
struct hash<hecl::FourCC> {
  size_t operator()(const hecl::FourCC& val) const noexcept { return val.toUint32(); }
};
} // namespace std

FMT_CUSTOM_FORMATTER(hecl::FourCC, "{:c}{:c}{:c}{:c}",
                     obj.getChars()[0], obj.getChars()[1], obj.getChars()[2], obj.getChars()[3])
FMT_CUSTOM_FORMATTER(hecl::DNAFourCC, "{:c}{:c}{:c}{:c}",
                     obj.getChars()[0], obj.getChars()[1], obj.getChars()[2], obj.getChars()[3])
<commit_msg>hecl/FourCC: Tidy up constructors<commit_after>#pragma once

#include <cstdint>
#include <cstddef>
#include <string>
#include "athena/DNA.hpp"

namespace hecl {

/**
 * @brief FourCC representation used within HECL's database
 *
 * FourCCs are efficient, mnemonic four-char-sequences used to represent types
 * while fitting comfortably in a 32-bit word. HECL uses a four-char array
 * to remain endian-independent.
 */
class FourCC {
protected:
  union {
    char fcc[4];
    uint32_t num = 0;
  };

public:
  // Sentinel FourCC
  constexpr FourCC() noexcept = default;
  constexpr FourCC(const FourCC& other) noexcept = default;
  constexpr FourCC(FourCC&& other) noexcept = default;
  constexpr FourCC(const char* name) noexcept : num(*(uint32_t*)name) {}
  constexpr FourCC(uint32_t n) noexcept : num(n) {}

  constexpr FourCC& operator=(const FourCC&) noexcept = default;
  constexpr FourCC& operator=(FourCC&&) noexcept = default;

  bool operator==(const FourCC& other) const { return num == other.num; }
  bool operator!=(const FourCC& other) const { return num != other.num; }
  bool operator==(const char* other) const { return num == *(uint32_t*)other; }
  bool operator!=(const char* other) const { return num != *(uint32_t*)other; }
  bool operator==(int32_t other) const { return num == uint32_t(other); }
  bool operator!=(int32_t other) const { return num != uint32_t(other); }
  bool operator==(uint32_t other) const { return num == other; }
  bool operator!=(uint32_t other) const { return num != other; }

  std::string toString() const { return std::string(fcc, 4); }
  uint32_t toUint32() const { return num; }
  const char* getChars() const { return fcc; }
  char* getChars() { return fcc; }
  bool IsValid() const { return num != 0; }
};
#define FOURCC(chars) FourCC(SBIG(chars))

using BigDNA = athena::io::DNA<athena::Big>;

/** FourCC with DNA read/write */
class DNAFourCC final : public BigDNA, public FourCC {
public:
  DNAFourCC() : FourCC() {}
  DNAFourCC(const FourCC& other) : FourCC() { num = other.toUint32(); }
  DNAFourCC(const char* name) : FourCC(name) {}
  DNAFourCC(uint32_t n) : FourCC(n) {}
  AT_DECL_EXPLICIT_DNA_YAML
};
template <>
inline void DNAFourCC::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {
  r.readUBytesToBuf(fcc, 4);
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
  w.writeUBytes((atUint8*)fcc, 4);
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
  std::string rs = r.readString(nullptr);
  strncpy(fcc, rs.c_str(), 4);
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) {
  w.writeString(nullptr, std::string(fcc, 4));
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
  s += 4;
}

} // namespace hecl

namespace std {
template <>
struct hash<hecl::FourCC> {
  size_t operator()(const hecl::FourCC& val) const noexcept { return val.toUint32(); }
};
} // namespace std

FMT_CUSTOM_FORMATTER(hecl::FourCC, "{:c}{:c}{:c}{:c}",
                     obj.getChars()[0], obj.getChars()[1], obj.getChars()[2], obj.getChars()[3])
FMT_CUSTOM_FORMATTER(hecl::DNAFourCC, "{:c}{:c}{:c}{:c}",
                     obj.getChars()[0], obj.getChars()[1], obj.getChars()[2], obj.getChars()[3])
<|endoftext|>


<commit_before>/*
 * Copyright 2020 Google LLC
 *
 * 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 "ecclesia/magent/redfish/indus/chassis.h"

#include <string>
#include <utility>

#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "ecclesia/magent/redfish/core/json_helper.h"
#include "ecclesia/magent/redfish/core/redfish_keywords.h"
#include "ecclesia/magent/redfish/core/resource.h"
#include "ecclesia/magent/sysmodel/x86/chassis.h"
#include "ecclesia/magent/sysmodel/x86/fru.h"
#include "ecclesia/magent/sysmodel/x86/sysmodel.h"
#include "json/value.h"
#include "tensorflow_serving/util/net_http/server/public/response_code_enum.h"
#include "tensorflow_serving/util/net_http/server/public/server_request_interface.h"

namespace ecclesia {
namespace {

absl::optional<SysmodelFru> GetFruInfo(SystemModel *system_model,
                                       absl::string_view fru_name) {
  SysmodelFruReaderIntf *fru_reader = system_model->GetFruReader(fru_name);
  if (!fru_reader) return absl::nullopt;
  absl::optional<SysmodelFru> fru = fru_reader->Read();
  if (!fru.has_value()) return absl::nullopt;
  return std::move(*fru);
}

}  // namespace

void Chassis::Get(tensorflow::serving::net_http::ServerRequestInterface *req,
                  const ParamsType &params) {
  if (params.size() != 1 || !absl::holds_alternative<std::string>(params[0])) {
    return;
  }
  auto chassis_req_name = std::get<std::string>(params[0]);
  std::string chassis_name = chassis_req_name;
  // The conversion below is to seamlessly support the existing name "chassis".
  // This should be cleaned up.
  if (chassis_req_name == "chassis") {
    chassis_name = "Indus";
  }
  absl::optional<ChassisId> found_chassis =
      system_model_->GetChassisByName(chassis_name);
  if (!found_chassis.has_value()) {
    req->ReplyWithStatus(
        tensorflow::serving::net_http::HTTPStatusCode::NOT_FOUND);
    return;
  }
  const ChassisId &chassis_id = found_chassis.value();
  Json::Value json;
  json[kOdataType] = "#Chassis.v1_6_0.Chassis";
  json[kOdataId] = std::string(req->uri_path());
  json[kOdataContext] = "/redfish/v1/$metadata#Chassis.Chassis";
  json[kChassisType] = GetChassisTypeAsString(chassis_id);

  json[kName] = absl::StrFormat("%s Chassis", ChassisIdToString(chassis_id));
  json[kId] = chassis_req_name;

  std::string fru_name;
  if (chassis_id == ChassisId::kIndus) {
    fru_name = "motherboard";
  } else {
    fru_name = ChassisIdToString(chassis_id);
  }

  auto found_fru = GetFruInfo(system_model_, fru_name);
  if (found_fru.has_value()) {
    const SysmodelFru &fru = found_fru.value();
    json[kPartNumber] = std::string(fru.GetPartNumber());
    json[kSerialNumber] = std::string(fru.GetSerialNumber());
    json[kManufacturer] = std::string(fru.GetManufacturer());
  }

  auto *assembly = GetJsonObject(&json, "Assembly");
  (*assembly)[kOdataId] = absl::StrCat(req->uri_path(), "/Assembly");

  auto *links = GetJsonObject(&json, kLinks);
  auto *computer_systems = GetJsonArray(links, kComputerSystems);
  Json::Value linked_computer_systems;
  linked_computer_systems[kOdataId] = kComputerSystemUri;
  computer_systems->append(linked_computer_systems);

  auto *sensors = GetJsonObject(&json, kSensor);
  (*sensors)[kOdataId] = absl::StrCat(req->uri_path(), "/Sensors");

  if (chassis_id == ChassisId::kIndus) {
    auto *thermal = GetJsonObject(&json, kThermal);
    (*thermal)[kOdataId] = kThermalUri;
  }

  JSONResponseOK(json, req);
}

}  // namespace ecclesia
<commit_msg>Internal change<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * 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 "ecclesia/magent/redfish/indus/chassis.h"

#include <string>
#include <utility>

#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "ecclesia/magent/redfish/core/json_helper.h"
#include "ecclesia/magent/redfish/core/redfish_keywords.h"
#include "ecclesia/magent/redfish/core/resource.h"
#include "ecclesia/magent/sysmodel/x86/chassis.h"
#include "ecclesia/magent/sysmodel/x86/fru.h"
#include "ecclesia/magent/sysmodel/x86/sysmodel.h"
#include "json/value.h"
#include "tensorflow_serving/util/net_http/server/public/response_code_enum.h"
#include "tensorflow_serving/util/net_http/server/public/server_request_interface.h"

namespace ecclesia {
namespace {

absl::optional<SysmodelFru> GetFruInfo(SystemModel *system_model,
                                       absl::string_view fru_name) {
  SysmodelFruReaderIntf *fru_reader = system_model->GetFruReader(fru_name);
  if (!fru_reader) return absl::nullopt;
  absl::optional<SysmodelFru> fru = fru_reader->Read();
  if (!fru.has_value()) return absl::nullopt;
  return std::move(*fru);
}

}  // namespace

void Chassis::Get(tensorflow::serving::net_http::ServerRequestInterface *req,
                  const ParamsType &params) {
  if (params.size() != 1 || !absl::holds_alternative<std::string>(params[0])) {
    return;
  }
  auto chassis_req_name = std::get<std::string>(params[0]);
  std::string chassis_name = chassis_req_name;
  // The conversion below is to seamlessly support the existing name "chassis".
  // This should be cleaned up.
  if (chassis_req_name == "chassis") {
    chassis_name = "Indus";
  }
  absl::optional<ChassisId> found_chassis =
      system_model_->GetChassisByName(chassis_name);
  if (!found_chassis.has_value()) {
    req->ReplyWithStatus(
        tensorflow::serving::net_http::HTTPStatusCode::NOT_FOUND);
    return;
  }
  const ChassisId &chassis_id = found_chassis.value();
  Json::Value json;
  json[kOdataType] = "#Chassis.v1_6_0.Chassis";
  json[kOdataId] = std::string(req->uri_path());
  json[kOdataContext] = "/redfish/v1/$metadata#Chassis.Chassis";
  json[kChassisType] = GetChassisTypeAsString(chassis_id);

  json[kName] = absl::StrFormat("%s Chassis", ChassisIdToString(chassis_id));
  json[kId] = chassis_req_name;

  std::string fru_name;
  if (chassis_id == ChassisId::kIndus) {
    fru_name = "motherboard";
  } else {
    fru_name = ChassisIdToString(chassis_id);
  }

  auto found_fru = GetFruInfo(system_model_, fru_name);
  if (found_fru.has_value()) {
    const SysmodelFru &fru = found_fru.value();
    json[kPartNumber] = std::string(fru.GetPartNumber());
    json[kSerialNumber] = std::string(fru.GetSerialNumber());
    json[kManufacturer] = std::string(fru.GetManufacturer());
  }

  auto *assembly = GetJsonObject(&json, "Assembly");
  (*assembly)[kOdataId] = absl::StrCat(req->uri_path(), "/Assembly");

  auto *links = GetJsonObject(&json, kLinks);
  auto *computer_systems = GetJsonArray(links, kComputerSystems);
  Json::Value linked_computer_systems;
  linked_computer_systems[kOdataId] = kComputerSystemUri;
  computer_systems->append(linked_computer_systems);

  if (chassis_id == ChassisId::kSleipnir) {
    auto *sensors = GetJsonObject(&json, kSensor);
    (*sensors)[kOdataId] = absl::StrCat(req->uri_path(), "/Sensors");
  }

  if (chassis_id == ChassisId::kIndus) {
    auto *thermal = GetJsonObject(&json, kThermal);
    (*thermal)[kOdataId] = kThermalUri;
  }

  JSONResponseOK(json, req);
}

}  // namespace ecclesia
<|endoftext|>


<commit_before>#include <iostream>
#include <string>

#include <stdio.h>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <vector>
#include <cstdlib>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;

#include "execute.h"

void Command::addArg(string temp)
{
	this->argList.push_back(temp);
	return;
}

void Command::testfunc(const vector <string> &list, bool &res)
{
	struct stat temp;
	string flag;
	string pathF;

	if (list.size() == 2) // tests whether the length of the
	{						// command is correct
		flag = "-e";
		pathF = list.at(1);
	}
	else if ( list.size() == 3)
	{
		flag = list.at(1);
		pathF = list.at(2);
	}
	else
	{
		res = false;
		return;
	}

	if (stat(pathF.c_str(),&temp) == 0) // tests whether file exists
	{
		res = true;
	}
	else
	{
		res = false; // does not exist
		perror("stat");
		return;
	}

	if (flag == "-e")
	{
		cout << "(true)" << endl;
        res = true;
        return;
	}
	else if (flag == "-f")
	{								// tests if it is a regular file
        if (S_ISREG(temp.st_mode))
        {
            cout << "(true)" << endl;
            res = true;
            return;

        }
        else
        {
            cout << "(false)" << endl;
            res = false;
            return;
        }
    }
    else if (flag == "-d")
	{								// tests if it is a directory
        if (S_ISDIR(temp.st_mode))
        {
            cout << "(true)" << endl;
            res = true;
            return;
        }
        else
        {
            cout << "(false)" << endl;
            res = false;
            return;
        }
    }
	else 				// if the flag is invalid, it will ouput error
	{
        cout << "Error:" << flag << " is not a valid flag."  << endl;
        res = false;
        return;
    }

}

bool Command::execution()
{
    bool result = true; // this is the return bool
    //cout << "Starting exicution" << endl;

    if (argList[0] == "test")
    {
    	testfunc(argList, result);
    	return result;
    }

    // for (unsigned int i = 0; i < argList.size(); i++)
    // {
    // 	cout << argList.at(i) << " ";
    // }
    // cout << endl;

	char** newArg = new char* [this->argList.size() + 1];

	if(this->command == "exit")
	{
		exit(0);
	}

    //cout << "Passed exit check" << endl;

	for(unsigned i = 0; i < this->argList.size(); ++i)
	{
		newArg[i] = new char[argList.at(i).size() + 1];
		std::strcpy(newArg[i], argList[i].c_str());
	}

	//cout << "Passed Strcpy" << endl;

	newArg[this->argList.size()] = NULL;

	// for(unsigned i = 0; i < this->argList.size(); ++i)
	// {
	//     printf("%s\n", newArg[i]);
	// }

	// cout << this->command << endl;

	//cout << "Passed bool result = true" << endl;

	pid_t pid = fork();

	if ( pid < 0)
	{
		perror("Fork");
		exit(-1);
	}
	else if (pid >= 0)
	{
		if (pid == 0) //child process
		{
			if(execvp(newArg[0], newArg) == -1)
			{
				result = false;
				perror("execvp");
				exit(1);
			}
			// printf("child: %d\n", pid);

		}
		else if (pid > 0) //parent process
		{
			int status;
			if(waitpid(pid, &status, 0) < 0)
			{
	        	perror("wait");
	    	}

	        if ( WEXITSTATUS(status) > 0 || WEXITSTATUS(status) < 0 )
	        {
	            result = false;
	        }

			// printf("parent: %d\n", pid);
		}
	}

    //cout << "Deleting arg" << endl;

	for(unsigned i = 0; i < this->argList.size(); ++i)
	{
		delete[] newArg[i];
	}

	delete[] newArg;

	// if (result == true)
	// {
	// 	cout << "true\n";
	// }
	// else
	// {
	// 	cout << "false\n";
	// }

	return result;
}

bool ANND::execution()
{
	if ( this->leftChild->execution() == true)
	{
	   if(this->rightChild->execution() == true)
	   {
		   return true;
	   }
	   else
	   {
		   return false;
	   }
	}
	else
	{
		return false;
	 }
}

bool ORR::execution()
{
	if ( this->leftChild->execution() == true)
	{
		return true;
	}
	else
	{
		if(this->rightChild->execution() == true)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}

bool Scolon::execution()
{
	this->leftChild->execution();
	if (this->rightChild != NULL)
	{
		if (this->rightChild->execution() == true)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return true;
	}
}

// int main()
// {
// 	Command temp("echo");
// 	temp.addArg("echo");
// 	temp.addArg("111");

// 	Command temp1("echo");
// 	temp1.addArg("echoo");
// 	temp1.addArg("222");

// 	Base* temp = new Command temp(vector);

// 	Command temp2("echo");
// 	temp2.addArg("echo");
// 	temp2.addArg("333");

// 	// temp.execution();
// 	// temp1.execution();
// 	// temp2.execution();

// 	Base* tempp = &temp;
// 	Base* tempp1 = &temp1;
// 	Base* tempp2 = &temp2;

// 	ANND temppp(tempp, tempp1);
// 	Base* tempppp = &temppp;
// 	ANND temppp1(&temppp, &temp2);

// 	ANND temppp(tempp, tempp1);
// 	Base* tempppp = &temppp;
// 	ANND temppp1(tempppp, &temp2);

// 	temppp1.execution();

// 	return 0;
// }

<commit_msg>fixed output<commit_after>#include <iostream>
#include <string>

#include <stdio.h>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <vector>
#include <cstdlib>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;

#include "execute.h"

void Command::addArg(string temp)
{
	this->argList.push_back(temp);
	return;
}

void Command::testfunc(const vector <string> &list, bool &res)
{
	struct stat temp;
	string flag;
	string pathF;

	if (list.size() == 2) // tests whether the length of the
	{						// command is correct
		flag = "-e";
		pathF = list.at(1);
	}
	else if ( list.size() == 3)
	{
		flag = list.at(1);
		pathF = list.at(2);
	}
	else
	{
		res = false;
		return;
	}

	if (stat(pathF.c_str(),&temp) == 0) // tests whether file exists
	{
		res = true;
	}
	else
	{
		res = false; // does not exist
		//perror("stat");
		cout << "(false)" << endl;
		return;
	}

	if (flag == "-e")
	{
		cout << "(true)" << endl;
        res = true;
        return;
	}
	else if (flag == "-f")
	{								// tests if it is a regular file
        if (S_ISREG(temp.st_mode))
        {
            cout << "(true)" << endl;
            res = true;
            return;

        }
        else
        {
            cout << "(false)" << endl;
            res = false;
            return;
        }
    }
    else if (flag == "-d")
	{								// tests if it is a directory
        if (S_ISDIR(temp.st_mode))
        {
            cout << "(true)" << endl;
            res = true;
            return;
        }
        else
        {
            cout << "(false)" << endl;
            res = false;
            return;
        }
    }
	else 				// if the flag is invalid, it will ouput error
	{
        cout << "Error:" << flag << " is not a valid flag."  << endl;
        res = false;
        return;
    }

}

bool Command::execution()
{
    bool result = true; // this is the return bool
    //cout << "Starting exicution" << endl;

    if (argList[0] == "test")
    {
    	testfunc(argList, result);
    	return result;
    }

    // for (unsigned int i = 0; i < argList.size(); i++)
    // {
    // 	cout << argList.at(i) << " ";
    // }
    // cout << endl;

	char** newArg = new char* [this->argList.size() + 1];

	if(this->command == "exit")
	{
		exit(0);
	}

    //cout << "Passed exit check" << endl;

	for(unsigned i = 0; i < this->argList.size(); ++i)
	{
		newArg[i] = new char[argList.at(i).size() + 1];
		std::strcpy(newArg[i], argList[i].c_str());
	}

	//cout << "Passed Strcpy" << endl;

	newArg[this->argList.size()] = NULL;

	// for(unsigned i = 0; i < this->argList.size(); ++i)
	// {
	//     printf("%s\n", newArg[i]);
	// }

	// cout << this->command << endl;

	//cout << "Passed bool result = true" << endl;

	pid_t pid = fork();

	if ( pid < 0)
	{
		perror("Fork");
		exit(-1);
	}
	else if (pid >= 0)
	{
		if (pid == 0) //child process
		{
			if(execvp(newArg[0], newArg) == -1)
			{
				result = false;
				perror("execvp");
				exit(1);
			}
			// printf("child: %d\n", pid);

		}
		else if (pid > 0) //parent process
		{
			int status;
			if(waitpid(pid, &status, 0) < 0)
			{
	        	perror("wait");
	    	}

	        if ( WEXITSTATUS(status) > 0 || WEXITSTATUS(status) < 0 )
	        {
	            result = false;
	        }

			// printf("parent: %d\n", pid);
		}
	}

    //cout << "Deleting arg" << endl;

	for(unsigned i = 0; i < this->argList.size(); ++i)
	{
		delete[] newArg[i];
	}

	delete[] newArg;

	// if (result == true)
	// {
	// 	cout << "true\n";
	// }
	// else
	// {
	// 	cout << "false\n";
	// }

	return result;
}

bool ANND::execution()
{
	if ( this->leftChild->execution() == true)
	{
	   if(this->rightChild->execution() == true)
	   {
		   return true;
	   }
	   else
	   {
		   return false;
	   }
	}
	else
	{
		return false;
	 }
}

bool ORR::execution()
{
	if ( this->leftChild->execution() == true)
	{
		return true;
	}
	else
	{
		if(this->rightChild->execution() == true)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}

bool Scolon::execution()
{
	this->leftChild->execution();
	if (this->rightChild != NULL)
	{
		if (this->rightChild->execution() == true)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return true;
	}
}

// int main()
// {
// 	Command temp("echo");
// 	temp.addArg("echo");
// 	temp.addArg("111");

// 	Command temp1("echo");
// 	temp1.addArg("echoo");
// 	temp1.addArg("222");

// 	Base* temp = new Command temp(vector);

// 	Command temp2("echo");
// 	temp2.addArg("echo");
// 	temp2.addArg("333");

// 	// temp.execution();
// 	// temp1.execution();
// 	// temp2.execution();

// 	Base* tempp = &temp;
// 	Base* tempp1 = &temp1;
// 	Base* tempp2 = &temp2;

// 	ANND temppp(tempp, tempp1);
// 	Base* tempppp = &temppp;
// 	ANND temppp1(&temppp, &temp2);

// 	ANND temppp(tempp, tempp1);
// 	Base* tempppp = &temppp;
// 	ANND temppp1(tempppp, &temp2);

// 	temppp1.execution();

// 	return 0;
// }

<|endoftext|>