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

#include <vlCore/Log.hpp>
#include <vlCore/checks.hpp>
#include <vlCore/VLSettings.hpp>
#include <vlCore/Vector3.hpp>
#include <vlCore/Say.hpp>
#include <vlCore/ScopedMutex.hpp>
#include <vlCore/version.hpp>
#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace vl;

namespace
{
#if defined(VL_PLATFORM_WINDOWS)
  struct ScopedColor
  {
    CONSOLE_SCREEN_BUFFER_INFO screen_info;
    WORD color;
    ScopedColor(WORD c): color(c)
    {
      HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
      GetConsoleScreenBufferInfo(
        hConsole,
        &screen_info
      );
      SetConsoleTextAttribute(hConsole, c);
    }
    ~ScopedColor()
    {
      // restore the color
      HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
      SetConsoleTextAttribute(hConsole,screen_info.wAttributes);
    }
  };
  #define SET_TEXT_COLOR_YELLOW() ScopedColor set_scoped_color(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
  #define SET_TEXT_COLOR_RED()    ScopedColor set_scoped_color(FOREGROUND_RED|FOREGROUND_INTENSITY);
  #define SET_TEXT_COLOR_PURPLE() ScopedColor set_scoped_color(FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
  #define SET_TEXT_COLOR_GREEN() ScopedColor set_scoped_color(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
  #define SET_TEXT_COLOR_BLUE() ScopedColor set_scoped_color(FOREGROUND_BLUE|FOREGROUND_INTENSITY);
#else
  struct ScopedColor
  {
    ScopedColor(const char* color)
    {
      //30 black foreground
      //31 red foreground
      //32 green foreground
      //33 brown foreground
      //34 blue foreground
      //35 magenta (purple) foreground
      //36 cyan (light blue) foreground
      //37 gray foreground

      //40 black background
      //41 red background
      //42 green background
      //43 brown background
      //44 blue background
      //45 magenta background
      //46 cyan background
      //47 white background

      //0 reset all attributes to their defaults
      //1 set bold
      //5 set blink
      //7 set reverse video
      //22 set normal intensity
      //25 blink off
      //27 reverse video off

      // example:
      // "\033[34mThis is blue.\033[0m"
      // "\033[45;37mGrey on purple.\033[0m"

      puts(color);
    }
    ~ScopedColor()
    {
      // restore normal color
      puts("\033[0m");
    }
  };
  #define SET_TEXT_COLOR_YELLOW() ScopedColor set_scoped_color("\033[1;33m");
  #define SET_TEXT_COLOR_RED()    ScopedColor set_scoped_color("\033[31m");
  #define SET_TEXT_COLOR_PURPLE() ScopedColor set_scoped_color("\033[1;31m");
  #define SET_TEXT_COLOR_GREEN()  ScopedColor set_scoped_color("\033[1;32m");
  #define SET_TEXT_COLOR_BLUE()  ScopedColor set_scoped_color("\033[1;34m");
#endif
}
//-----------------------------------------------------------------------------
// Log
//-----------------------------------------------------------------------------
void Log::notify(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_GREEN()
  if(defLogger() && globalSettings()->verbosityLevel() != vl::VEL_VERBOSITY_SILENT)
    defLogger()->printImplementation(LL_LogNotify, log);
}
//-----------------------------------------------------------------------------
void Log::print(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  if(defLogger() && globalSettings()->verbosityLevel() != vl::VEL_VERBOSITY_SILENT)
    defLogger()->printImplementation(LL_LogPrint, log);
}
//-----------------------------------------------------------------------------
void Log::debug(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_BLUE()
  if(defLogger() && globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_DEBUG)
    defLogger()->printImplementation(LL_LogDebug, log);
}
//-----------------------------------------------------------------------------
void Log::warning(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_YELLOW()
  if(defLogger() && globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_ERROR)
    defLogger()->printImplementation(LL_LogWarning, log);
}
//-----------------------------------------------------------------------------
void Log::error(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_RED()
  if(defLogger() && globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_ERROR)
    defLogger()->printImplementation(LL_LogError, log);
}
//-----------------------------------------------------------------------------
void Log::bug(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_PURPLE()
  if(defLogger() && globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_ERROR)
    defLogger()->printImplementation(LL_LogBug, log);
}
//------------------------------------------------------------------------------
void Log::logSystemInfo()
{
  #if defined(_MSC_VER)
    const char* compiler = "MSVC";
  #elif defined(__GNUG__)
    const char* compiler = "GCC";
  #else
    const char* compiler = "UNKNOWN";
  #endif

  #if defined(DEBUG) || !defined(NDEBUG)
    const char* build_type = "DEBUG";
  #else
    const char* build_type = "RELEASE";
  #endif

  print( Say("Visualization Library v%n.%n.%n [%s]\n%s - %s - %s compiler [%s] [%s]\n")
    << VL_Major << VL_Minor << VL_Build
    << (sizeof(vec3) == sizeof(fvec3) ? "f32" : "f64")
    << __DATE__ << __TIME__ << compiler << build_type
    << (sizeof(void*) == 4 ? "x32" : "x64") );

  print("\n --- Environment ---\n");
  const char* val = getenv("VL_LOGFILE_PATH");
  if (val)
    print( Say("VL_LOGFILE_PATH = %s\n") << val );
  else
    print("VL_LOGFILE_PATH <not present>\n");

  val = getenv("VL_DATA_PATH");
  if (val)
    print( Say("VL_DATA_PATH = %s\n") << val );
  else
    print("VL_DATA_PATH <not present>\n");

  val = getenv("VL_VERBOSITY_LEVEL");
  if (val)
    print( Say("VL_VERBOSITY_LEVEL = %s\n") << val );
  else
    print("VL_VERBOSITY_LEVEL <not present>\n");

  val = getenv("VL_CHECK_GL_STATES");
  if (val)
    print( Say("VL_CHECK_GL_STATES = %s\n") << val );
  else
    print("VL_CHECK_GL_STATES <not present>\n");

  print("\n --- Global Settings --- \n");
  print( Say("Log file  = %s\n") << globalSettings()->defaultLogPath() );
  print( Say("Data path = %s\n") << globalSettings()->defaultDataPath() );
  print("Verbosity level = ");
  switch(globalSettings()->verbosityLevel())
  {
    /*case vl::VEL_VERBOSITY_SILENT: print("SILENT\n"); break;*/
    case vl::VEL_VERBOSITY_ERROR:  print("ERROR\n"); break;
    case vl::VEL_VERBOSITY_NORMAL: print("NORMAL\n"); break;
    case vl::VEL_VERBOSITY_DEBUG:  print("DEBUG\n"); break;
    default: break;
  }
  print( Say("Check OpenGL States = %s\n") << (globalSettings()->checkOpenGLStates()?"YES":"NO") );

  print("\n");
}
//------------------------------------------------------------------------------
void vl::log_failed_check(const char* expr, const char* file, int line)
{
  VL_LOG_ERROR << "Condition '" << expr << "' failed at " << file << ":" << line << "\n";
  fflush(stdout);
  fflush(stderr);

  #if defined(VL_PLATFORM_WINDOWS) && VL_MESSAGEBOX_CHECK == 1
     String msg = Say("Condition \"%s\" failed.\n\n%s:%n\n") << expr << file << line;
     MessageBox(NULL, (wchar_t*)msg.ptr(), L"Visualization Library Debug", MB_OK | MB_ICONEXCLAMATION);
  #endif
}
//-----------------------------------------------------------------------------
// Log mutex.
//-----------------------------------------------------------------------------
IMutex* Log::mLogMutex = NULL;
//-----------------------------------------------------------------------------
// StandardLog
//-----------------------------------------------------------------------------
void StandardLog::setLogFile(const String& file)
{
  mLogFile = file;

  if (mFile.is_open())
    mFile.close();

  if (!file.empty())
    mFile.open(file.toStdString().c_str());
}
//-----------------------------------------------------------------------------
void StandardLog::printImplementation(ELogLevel, const String& log)
{
  if (log.empty())
    return;

  std::string stdstr = log.toStdString();
  std::cout << stdstr << std::flush;

  if (mFile.is_open())
    mFile << stdstr << std::flush;
}
//-----------------------------------------------------------------------------
<commit_msg>fixed logging under Linux<commit_after>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.org                                               */
/*                                                                                */
/*  Copyright (c) 2005-2011, Michele Bosi                                             */
/*  All rights reserved.                                                              */
/*                                                                                */
/*  Redistribution and use in source and binary forms, with or without modification,  */
/*  are permitted provided that the following conditions are met:                     */
/*                                                                                */
/*  - Redistributions of source code must retain the above copyright notice, this     */
/*  list of conditions and the following disclaimer.                                  */
/*                                                                                */
/*  - Redistributions in binary form must reproduce the above copyright notice, this  */
/*  list of conditions and the following disclaimer in the documentation and/or       */
/*  other materials provided with the distribution.                                   */
/*                                                                                */
/*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
/*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
/*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
/*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
/*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
/*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
/*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
/*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
/*                                                                                */
/**************************************************************************************/

#include <vlCore/Log.hpp>
#include <vlCore/checks.hpp>
#include <vlCore/VLSettings.hpp>
#include <vlCore/Vector3.hpp>
#include <vlCore/Say.hpp>
#include <vlCore/ScopedMutex.hpp>
#include <vlCore/version.hpp>
#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace vl;

namespace
{
#if defined(VL_PLATFORM_WINDOWS)
  struct ScopedColor
  {
    CONSOLE_SCREEN_BUFFER_INFO screen_info;
    WORD color;
    ScopedColor(WORD c): color(c)
    {
      HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
      GetConsoleScreenBufferInfo(
        hConsole,
        &screen_info
      );
      SetConsoleTextAttribute(hConsole, c);
    }
    ~ScopedColor()
    {
      // restore the color
      HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
      SetConsoleTextAttribute(hConsole,screen_info.wAttributes);
    }
  };
  #define SET_TEXT_COLOR_YELLOW() ScopedColor set_scoped_color(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
  #define SET_TEXT_COLOR_RED()    ScopedColor set_scoped_color(FOREGROUND_RED|FOREGROUND_INTENSITY);
  #define SET_TEXT_COLOR_PURPLE() ScopedColor set_scoped_color(FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
  #define SET_TEXT_COLOR_GREEN() ScopedColor set_scoped_color(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
  #define SET_TEXT_COLOR_BLUE() ScopedColor set_scoped_color(FOREGROUND_BLUE|FOREGROUND_INTENSITY);
#else
  struct ScopedColor
  {
    ScopedColor(const char* color)
    {
      //30 black foreground
      //31 red foreground
      //32 green foreground
      //33 brown foreground
      //34 blue foreground
      //35 magenta (purple) foreground
      //36 cyan (light blue) foreground
      //37 gray foreground

      //40 black background
      //41 red background
      //42 green background
      //43 brown background
      //44 blue background
      //45 magenta background
      //46 cyan background
      //47 white background

      //0 reset all attributes to their defaults
      //1 set bold
      //5 set blink
      //7 set reverse video
      //22 set normal intensity
      //25 blink off
      //27 reverse video off

      // example:
      // "\033[34mThis is blue.\033[0m"
      // "\033[45;37mGrey on purple.\033[0m"

      printf("%s", color);
    }
    ~ScopedColor()
    {
      // restore normal color
      printf("%s", "\033[0m");
    }
  };
  #define SET_TEXT_COLOR_YELLOW() ScopedColor set_scoped_color("\033[1;33m");
  #define SET_TEXT_COLOR_RED()    ScopedColor set_scoped_color("\033[31m");
  #define SET_TEXT_COLOR_PURPLE() ScopedColor set_scoped_color("\033[1;31m");
  #define SET_TEXT_COLOR_GREEN()  ScopedColor set_scoped_color("\033[1;32m");
  #define SET_TEXT_COLOR_BLUE()  ScopedColor set_scoped_color("\033[1;34m");
#endif
}
//-----------------------------------------------------------------------------
// Log
//-----------------------------------------------------------------------------
void Log::notify(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_GREEN()
  if(defLogger() && globalSettings()->verbosityLevel() != vl::VEL_VERBOSITY_SILENT)
    defLogger()->printImplementation(LL_LogNotify, log);
}
//-----------------------------------------------------------------------------
void Log::print(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  if(defLogger() && globalSettings()->verbosityLevel() != vl::VEL_VERBOSITY_SILENT)
    defLogger()->printImplementation(LL_LogPrint, log);
}
//-----------------------------------------------------------------------------
void Log::debug(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_BLUE()
  if(defLogger() && globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_DEBUG)
    defLogger()->printImplementation(LL_LogDebug, log);
}
//-----------------------------------------------------------------------------
void Log::warning(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_YELLOW()
  if(defLogger() && globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_ERROR)
    defLogger()->printImplementation(LL_LogWarning, log);
}
//-----------------------------------------------------------------------------
void Log::error(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_RED()
  if(defLogger() && globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_ERROR)
    defLogger()->printImplementation(LL_LogError, log);
}
//-----------------------------------------------------------------------------
void Log::bug(const String& log)
{
  //! Synchronize log across threads.
  ScopedMutex mutex(Log::logMutex());

  SET_TEXT_COLOR_PURPLE()
  if(defLogger() && globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_ERROR)
    defLogger()->printImplementation(LL_LogBug, log);
}
//------------------------------------------------------------------------------
void Log::logSystemInfo()
{
  #if defined(_MSC_VER)
    const char* compiler = "MSVC";
  #elif defined(__GNUG__)
    const char* compiler = "GCC";
  #else
    const char* compiler = "UNKNOWN";
  #endif

  #if defined(DEBUG) || !defined(NDEBUG)
    const char* build_type = "DEBUG";
  #else
    const char* build_type = "RELEASE";
  #endif

  print( Say("Visualization Library v%n.%n.%n [%s]\n%s - %s - %s compiler [%s] [%s]\n")
    << VL_Major << VL_Minor << VL_Build
    << (sizeof(vec3) == sizeof(fvec3) ? "f32" : "f64")
    << __DATE__ << __TIME__ << compiler << build_type
    << (sizeof(void*) == 4 ? "x32" : "x64") );

  print("\n --- Environment ---\n");
  const char* val = getenv("VL_LOGFILE_PATH");
  if (val)
    print( Say("VL_LOGFILE_PATH = %s\n") << val );
  else
    print("VL_LOGFILE_PATH <not present>\n");

  val = getenv("VL_DATA_PATH");
  if (val)
    print( Say("VL_DATA_PATH = %s\n") << val );
  else
    print("VL_DATA_PATH <not present>\n");

  val = getenv("VL_VERBOSITY_LEVEL");
  if (val)
    print( Say("VL_VERBOSITY_LEVEL = %s\n") << val );
  else
    print("VL_VERBOSITY_LEVEL <not present>\n");

  val = getenv("VL_CHECK_GL_STATES");
  if (val)
    print( Say("VL_CHECK_GL_STATES = %s\n") << val );
  else
    print("VL_CHECK_GL_STATES <not present>\n");

  print("\n --- Global Settings --- \n");
  print( Say("Log file  = %s\n") << globalSettings()->defaultLogPath() );
  print( Say("Data path = %s\n") << globalSettings()->defaultDataPath() );
  print("Verbosity level = ");
  switch(globalSettings()->verbosityLevel())
  {
    /*case vl::VEL_VERBOSITY_SILENT: print("SILENT\n"); break;*/
    case vl::VEL_VERBOSITY_ERROR:  print("ERROR\n"); break;
    case vl::VEL_VERBOSITY_NORMAL: print("NORMAL\n"); break;
    case vl::VEL_VERBOSITY_DEBUG:  print("DEBUG\n"); break;
    default: break;
  }
  print( Say("Check OpenGL States = %s\n") << (globalSettings()->checkOpenGLStates()?"YES":"NO") );

  print("\n");
}
//------------------------------------------------------------------------------
void vl::log_failed_check(const char* expr, const char* file, int line)
{
  VL_LOG_ERROR << "Condition '" << expr << "' failed at " << file << ":" << line << "\n";
  fflush(stdout);
  fflush(stderr);

  #if defined(VL_PLATFORM_WINDOWS) && VL_MESSAGEBOX_CHECK == 1
     String msg = Say("Condition \"%s\" failed.\n\n%s:%n\n") << expr << file << line;
     MessageBox(NULL, (wchar_t*)msg.ptr(), L"Visualization Library Debug", MB_OK | MB_ICONEXCLAMATION);
  #endif
}
//-----------------------------------------------------------------------------
// Log mutex.
//-----------------------------------------------------------------------------
IMutex* Log::mLogMutex = NULL;
//-----------------------------------------------------------------------------
// StandardLog
//-----------------------------------------------------------------------------
void StandardLog::setLogFile(const String& file)
{
  mLogFile = file;

  if (mFile.is_open())
    mFile.close();

  if (!file.empty())
    mFile.open(file.toStdString().c_str());
}
//-----------------------------------------------------------------------------
void StandardLog::printImplementation(ELogLevel, const String& log)
{
  if (log.empty())
    return;

  std::string stdstr = log.toStdString();
  std::cout << stdstr << std::flush;

  if (mFile.is_open())
    mFile << stdstr << std::flush;
}
//-----------------------------------------------------------------------------
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 <string>

#include <stout/gtest.hpp>
#include <stout/json.hpp>

#include <mesos/oci/spec.hpp>

#include "tests/mesos.hpp"

namespace image = ::oci::spec::image;

using std::string;

namespace mesos {
namespace internal {
namespace tests {

class OCISpecTest : public ::testing::Test {};

TEST_F(OCISpecTest, ParseDescriptor)
{
  const string json =
      R"~(
      {
        "mediaType": "application/vnd.oci.image.manifest.v1+json",
        "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
        "size": 7682,
        "urls": [
          "https://example.com/example-manifest"
        ]
      })~";

  Try<image::v1::Descriptor> descriptor =
      image::v1::parse<image::v1::Descriptor>(json);

  ASSERT_SOME(descriptor);

  EXPECT_EQ(
      "application/vnd.oci.image.manifest.v1+json",
      descriptor->mediatype());

  EXPECT_EQ(
      "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
      descriptor->digest());

  EXPECT_EQ(7682u, descriptor->size());

  EXPECT_EQ(
      "https://example.com/example-manifest",
      descriptor->urls(0));
}

TEST_F(OCISpecTest, ParseManifestList)
{
  const string json =
      R"~(
      {
        "schemaVersion": 2,
        "manifests": [
          {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "size": 7143,
            "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
            "platform": {
              "architecture": "ppc64le",
              "os": "linux",
              "os.version": "16.04"
            }
          },
          {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "size": 7682,
            "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
            "platform": {
              "architecture": "amd64",
              "os": "linux",
              "os.features": [
                "sse4"
              ]
            }
          }
        ],
        "annotations": {
          "com.example.key1": "value1",
          "com.example.key2": "value2"
        }
      })~";

  Try<image::v1::ManifestList> manifestList =
      image::v1::parse<image::v1::ManifestList>(json);

  ASSERT_SOME(manifestList);

  EXPECT_EQ(2u, manifestList->schemaversion());

  EXPECT_EQ(
      "application/vnd.oci.image.manifest.v1+json",
      manifestList->manifests(0).mediatype());

  EXPECT_EQ(7143u, manifestList->manifests(0).size());

  EXPECT_EQ(
      "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
      manifestList->manifests(0).digest());

  EXPECT_EQ(
      "ppc64le",
      manifestList->manifests(0).platform().architecture());

  EXPECT_EQ(
      "linux",
      manifestList->manifests(0).platform().os());

  EXPECT_EQ(
      "16.04",
      manifestList->manifests(0).platform().os_version());

  EXPECT_EQ(
      "sse4",
      manifestList->manifests(1).platform().os_features(0));

  EXPECT_EQ(
      "com.example.key1",
      manifestList->annotations(0).key());

  EXPECT_EQ(
      "value1",
      manifestList->annotations(0).value());

  EXPECT_EQ(
      "com.example.key2",
      manifestList->annotations(1).key());

  EXPECT_EQ(
      "value2",
      manifestList->annotations(1).value());
}

TEST_F(OCISpecTest, ParseManifest)
{
  const string json =
      R"~(
      {
        "schemaVersion": 2,
        "config": {
          "mediaType": "application/vnd.oci.image.config.v1+json",
          "size": 7023,
          "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7"
        },
        "layers": [
          {
            "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
            "size": 32654,
            "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f"
          },
          {
            "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
            "size": 16724,
            "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b"
          }
        ],
        "annotations": {
          "com.example.key1": "value1",
          "com.example.key2": "value2"
        }
      })~";

  Try<image::v1::Manifest> manifest=
      image::v1::parse<image::v1::Manifest>(json);

  ASSERT_SOME(manifest);

  EXPECT_EQ(2u, manifest->schemaversion());

  EXPECT_EQ(
      "application/vnd.oci.image.config.v1+json",
      manifest->config().mediatype());

  EXPECT_EQ(7023u, manifest->config().size());

  EXPECT_EQ(
      "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7",
      manifest->config().digest());

  EXPECT_EQ(
      "application/vnd.oci.image.layer.v1.tar+gzip",
      manifest->layers(0).mediatype());

  EXPECT_EQ(32654u, manifest->layers(0).size());

  EXPECT_EQ(
      "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
      manifest->layers(0).digest());

  EXPECT_EQ(
        "application/vnd.oci.image.layer.v1.tar+gzip",
        manifest->layers(1).mediatype());

  EXPECT_EQ(16724u, manifest->layers(1).size());

  EXPECT_EQ(
      "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b",
      manifest->layers(1).digest());

  EXPECT_EQ(
      "com.example.key1",
      manifest->annotations(0).key());

  EXPECT_EQ(
      "value1",
      manifest->annotations(0).value());

  EXPECT_EQ(
      "com.example.key2",
      manifest->annotations(1).key());

  EXPECT_EQ(
      "value2",
      manifest->annotations(1).value());
}

TEST_F(OCISpecTest, ParseConfiguration)
{
  const string json =
      R"~(
      {
        "created": "2015-10-31T22:22:56.015925234Z",
        "author": "Alyssa P. Hacker <alyspdev@example.com>",
        "architecture": "amd64",
        "os": "linux",
        "config": {
            "User": "alice",
            "ExposedPorts": {
                "8080/tcp": {}
            },
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "FOO=oci_is_a"
            ],
            "Entrypoint": [
                "/bin/my-app-binary"
            ],
            "Cmd": [
                "--config",
                "/etc/my-app.d/default.cfg"
            ],
            "Volumes": {
                "/var/job-result-data": {},
                "/var/log/my-app-logs": {}
            },
            "WorkingDir": "/home/alice",
            "Labels": {
                "com.example.project.git.commit": "45a939b2999782a3f005621a8d0f29aa387e1d6b",
                "com.example.project.git.url": "https://example.com/project.git"
            }
        },
        "rootfs": {
          "diff_ids": [
            "sha256:c6f988f4874bb0add23a778f753c65efe992244e148a1d2ec2a8b664fb66bbd1",
            "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
          ],
          "type": "layers"
        },
        "history": [
          {
            "created": "2015-10-31T22:22:54.690851953Z",
            "created_by": "/bin/sh -c #(nop) ADD file:a3bc1e842b69636f9df5256c49c5 in /"
          },
          {
            "created": "2015-10-31T22:22:55.613815829Z",
            "created_by": "/bin/sh -c #(nop) CMD [\"sh\"]",
            "empty_layer": true
          }
        ]
      })~";

  Try<image::v1::Configuration> configuration =
      image::v1::parse<image::v1::Configuration>(json);

  ASSERT_SOME(configuration);

  EXPECT_EQ(
      "2015-10-31T22:22:56.015925234Z",
      configuration->created());

  EXPECT_EQ(
      "Alyssa P. Hacker <alyspdev@example.com>",
      configuration->author());

  EXPECT_EQ(
      "amd64",
      configuration->architecture());

  EXPECT_EQ(
      "linux",
      configuration->os());

  EXPECT_EQ(
      "alice",
      configuration->config().user());

  EXPECT_EQ(
      "8080/tcp",
      configuration->config().exposedports(0));

  EXPECT_EQ(
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
      configuration->config().env(0));

  EXPECT_EQ(
      "FOO=oci_is_a",
      configuration->config().env(1));

  EXPECT_EQ(
      "/bin/my-app-binary",
      configuration->config().entrypoint(0));

  EXPECT_EQ(
      "--config",
      configuration->config().cmd(0));

  EXPECT_EQ(
      "/etc/my-app.d/default.cfg",
      configuration->config().cmd(1));

  EXPECT_EQ(
      "/var/job-result-data",
      configuration->config().volumes(0));

  EXPECT_EQ(
      "/var/log/my-app-logs",
      configuration->config().volumes(1));

  EXPECT_EQ(
      "/home/alice",
      configuration->config().workingdir());

  EXPECT_EQ(
      "com.example.project.git.commit",
      configuration->config().labels(0).key());

  EXPECT_EQ(
      "45a939b2999782a3f005621a8d0f29aa387e1d6b",
      configuration->config().labels(0).value());

  EXPECT_EQ(
      "com.example.project.git.url",
      configuration->config().labels(1).key());

  EXPECT_EQ(
      "https://example.com/project.git",
      configuration->config().labels(1).value());

  EXPECT_EQ(
      "sha256:c6f988f4874bb0add23a778f753c65efe992244e148a1d2ec2a8b664fb66bbd1",
      configuration->rootfs().diff_ids(0));

  EXPECT_EQ(
      "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef",
      configuration->rootfs().diff_ids(1));

  EXPECT_EQ(
      "layers",
      configuration->rootfs().type());

  EXPECT_EQ(
      "2015-10-31T22:22:54.690851953Z",
      configuration->history(0).created());

  EXPECT_EQ(
      "/bin/sh -c #(nop) ADD file:a3bc1e842b69636f9df5256c49c5 in /",
      configuration->history(0).created_by());

  EXPECT_EQ(
      true,
      configuration->history(1).empty_layer());
}

} // namespace tests {
} // namespace internal {
} // namespace mesos {
<commit_msg>Update OCI tests with the latest OCI image spec.<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 <string>

#include <stout/gtest.hpp>
#include <stout/json.hpp>

#include <mesos/oci/spec.hpp>

#include "tests/mesos.hpp"

namespace image = ::oci::spec::image;

using std::string;

namespace mesos {
namespace internal {
namespace tests {

class OCISpecTest : public ::testing::Test {};

TEST_F(OCISpecTest, ParseDescriptor)
{
  const string json =
      R"~(
      {
        "mediaType": "application/vnd.oci.image.manifest.v1+json",
        "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
        "size": 7682,
        "urls": [
          "https://example.com/example-manifest"
        ]
      })~";

  Try<image::v1::Descriptor> descriptor =
      image::v1::parse<image::v1::Descriptor>(json);

  ASSERT_SOME(descriptor);

  EXPECT_EQ(
      "application/vnd.oci.image.manifest.v1+json",
      descriptor->mediatype());

  EXPECT_EQ(
      "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
      descriptor->digest());

  EXPECT_EQ(7682u, descriptor->size());

  EXPECT_EQ(
      "https://example.com/example-manifest",
      descriptor->urls(0));
}

TEST_F(OCISpecTest, ParseIndex)
{
  const string json =
      R"~(
      {
        "schemaVersion": 2,
        "manifests": [
          {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "size": 7143,
            "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
            "platform": {
              "architecture": "ppc64le",
              "os": "linux",
              "os.version": "16.04"
            }
          },
          {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "size": 7682,
            "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
            "platform": {
              "architecture": "amd64",
              "os": "linux",
              "os.features": [
                "sse4"
              ]
            }
          }
        ],
        "annotations": {
          "com.example.key1": "value1",
          "com.example.key2": "value2"
        }
      })~";

  Try<image::v1::Index> index =
      image::v1::parse<image::v1::Index>(json);

  ASSERT_SOME(index);

  EXPECT_EQ(2u, index->schemaversion());

  EXPECT_EQ(
      "application/vnd.oci.image.manifest.v1+json",
      index->manifests(0).mediatype());

  EXPECT_EQ(7143u, index->manifests(0).size());

  EXPECT_EQ(
      "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
      index->manifests(0).digest());

  EXPECT_EQ(
      "ppc64le",
      index->manifests(0).platform().architecture());

  EXPECT_EQ(
      "linux",
      index->manifests(0).platform().os());

  EXPECT_EQ(
      "16.04",
      index->manifests(0).platform().os_version());

  EXPECT_EQ(
      "sse4",
      index->manifests(1).platform().os_features(0));

  EXPECT_EQ(
      "com.example.key1",
      index->annotations(0).key());

  EXPECT_EQ(
      "value1",
      index->annotations(0).value());

  EXPECT_EQ(
      "com.example.key2",
      index->annotations(1).key());

  EXPECT_EQ(
      "value2",
      index->annotations(1).value());
}

TEST_F(OCISpecTest, ParseManifest)
{
  const string json =
      R"~(
      {
        "schemaVersion": 2,
        "config": {
          "mediaType": "application/vnd.oci.image.config.v1+json",
          "size": 7023,
          "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7"
        },
        "layers": [
          {
            "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
            "size": 32654,
            "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f"
          },
          {
            "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
            "size": 16724,
            "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b"
          }
        ],
        "annotations": {
          "com.example.key1": "value1",
          "com.example.key2": "value2"
        }
      })~";

  Try<image::v1::Manifest> manifest=
      image::v1::parse<image::v1::Manifest>(json);

  ASSERT_SOME(manifest);

  EXPECT_EQ(2u, manifest->schemaversion());

  EXPECT_EQ(
      "application/vnd.oci.image.config.v1+json",
      manifest->config().mediatype());

  EXPECT_EQ(7023u, manifest->config().size());

  EXPECT_EQ(
      "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7",
      manifest->config().digest());

  EXPECT_EQ(
      "application/vnd.oci.image.layer.v1.tar+gzip",
      manifest->layers(0).mediatype());

  EXPECT_EQ(32654u, manifest->layers(0).size());

  EXPECT_EQ(
      "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
      manifest->layers(0).digest());

  EXPECT_EQ(
        "application/vnd.oci.image.layer.v1.tar+gzip",
        manifest->layers(1).mediatype());

  EXPECT_EQ(16724u, manifest->layers(1).size());

  EXPECT_EQ(
      "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b",
      manifest->layers(1).digest());

  EXPECT_EQ(
      "com.example.key1",
      manifest->annotations(0).key());

  EXPECT_EQ(
      "value1",
      manifest->annotations(0).value());

  EXPECT_EQ(
      "com.example.key2",
      manifest->annotations(1).key());

  EXPECT_EQ(
      "value2",
      manifest->annotations(1).value());
}

TEST_F(OCISpecTest, ParseConfiguration)
{
  const string json =
      R"~(
      {
        "created": "2015-10-31T22:22:56.015925234Z",
        "author": "Alyssa P. Hacker <alyspdev@example.com>",
        "architecture": "amd64",
        "os": "linux",
        "config": {
            "User": "alice",
            "ExposedPorts": {
                "8080/tcp": {}
            },
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "FOO=oci_is_a"
            ],
            "Entrypoint": [
                "/bin/my-app-binary"
            ],
            "Cmd": [
                "--config",
                "/etc/my-app.d/default.cfg"
            ],
            "Volumes": {
                "/var/job-result-data": {},
                "/var/log/my-app-logs": {}
            },
            "WorkingDir": "/home/alice",
            "Labels": {
                "com.example.project.git.commit": "45a939b2999782a3f005621a8d0f29aa387e1d6b",
                "com.example.project.git.url": "https://example.com/project.git"
            }
        },
        "rootfs": {
          "diff_ids": [
            "sha256:c6f988f4874bb0add23a778f753c65efe992244e148a1d2ec2a8b664fb66bbd1",
            "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
          ],
          "type": "layers"
        },
        "history": [
          {
            "created": "2015-10-31T22:22:54.690851953Z",
            "created_by": "/bin/sh -c #(nop) ADD file:a3bc1e842b69636f9df5256c49c5 in /"
          },
          {
            "created": "2015-10-31T22:22:55.613815829Z",
            "created_by": "/bin/sh -c #(nop) CMD [\"sh\"]",
            "empty_layer": true
          }
        ]
      })~";

  Try<image::v1::Configuration> configuration =
      image::v1::parse<image::v1::Configuration>(json);

  ASSERT_SOME(configuration);

  EXPECT_EQ(
      "2015-10-31T22:22:56.015925234Z",
      configuration->created());

  EXPECT_EQ(
      "Alyssa P. Hacker <alyspdev@example.com>",
      configuration->author());

  EXPECT_EQ(
      "amd64",
      configuration->architecture());

  EXPECT_EQ(
      "linux",
      configuration->os());

  EXPECT_EQ(
      "alice",
      configuration->config().user());

  EXPECT_EQ(
      "8080/tcp",
      configuration->config().exposedports(0));

  EXPECT_EQ(
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
      configuration->config().env(0));

  EXPECT_EQ(
      "FOO=oci_is_a",
      configuration->config().env(1));

  EXPECT_EQ(
      "/bin/my-app-binary",
      configuration->config().entrypoint(0));

  EXPECT_EQ(
      "--config",
      configuration->config().cmd(0));

  EXPECT_EQ(
      "/etc/my-app.d/default.cfg",
      configuration->config().cmd(1));

  EXPECT_EQ(
      "/var/job-result-data",
      configuration->config().volumes(0));

  EXPECT_EQ(
      "/var/log/my-app-logs",
      configuration->config().volumes(1));

  EXPECT_EQ(
      "/home/alice",
      configuration->config().workingdir());

  EXPECT_EQ(
      "com.example.project.git.commit",
      configuration->config().labels(0).key());

  EXPECT_EQ(
      "45a939b2999782a3f005621a8d0f29aa387e1d6b",
      configuration->config().labels(0).value());

  EXPECT_EQ(
      "com.example.project.git.url",
      configuration->config().labels(1).key());

  EXPECT_EQ(
      "https://example.com/project.git",
      configuration->config().labels(1).value());

  EXPECT_EQ(
      "sha256:c6f988f4874bb0add23a778f753c65efe992244e148a1d2ec2a8b664fb66bbd1",
      configuration->rootfs().diff_ids(0));

  EXPECT_EQ(
      "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef",
      configuration->rootfs().diff_ids(1));

  EXPECT_EQ(
      "layers",
      configuration->rootfs().type());

  EXPECT_EQ(
      "2015-10-31T22:22:54.690851953Z",
      configuration->history(0).created());

  EXPECT_EQ(
      "/bin/sh -c #(nop) ADD file:a3bc1e842b69636f9df5256c49c5 in /",
      configuration->history(0).created_by());

  EXPECT_EQ(
      true,
      configuration->history(1).empty_layer());
}

} // namespace tests {
} // namespace internal {
} // namespace mesos {
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <utility>

#include "linbox/blackbox/zero-one.h"
#include "linbox/field/modular.h"

#include "test-common.h"
#include "test-generic.h"

int main(int argc, char **argv) {
  bool pass = true;
  uint32 prime = 31337;
  size_t *rows, *cols, i;
  static size_t n = 1000, iter = 1;

  static Argument args[] = {
    { 'n', "-n N", "Set dimension of test matrix to NxN.", TYPE_INT, &n },
    { 'q', "-q Q", "Operate over the \"field\" GF(Q) [1].", TYPE_INT, &prime },
    { 'i', "-i I", "Perform each test for I iterations.", TYPE_INT, &iter},
	{ '\0' }
  };

  parseArguments(argc, argv, args);

  typedef LinBox::ZeroOne<LinBox::Modular<LinBox::uint32> > Matrix;

  LinBox::Modular<LinBox::uint32> afield(prime);

  rows = new size_t[3 * n];
  cols = new size_t[3 * n];

  // "arrow" matrix
  for(i = 0; i < n; i++) { rows[i] = 0; cols[i] = i; } // first row
  for(i = 0; i < n; i++) { rows[n+i] = i; cols[i] = 0; } // first col
  for(i = 0; i < n; i++) { rows[2*n+i] = i; cols[2*n+i] = i; } // diag
  Matrix testMatrix(afield, rows, cols, n, n, 3*n - 2);

  /*
  for(i = 0; i < n; i++) { rows[i] = i; cols[i] = i; } // diag
  Matrix testMatrix(afield, rows, cols, n, n, n);
  */
/*
  Matrix testMatrix(afield);
  ifstream mat_in("data/n4c6.b9.186558x198895.sms");
  testMatrix.read(mat_in);
  std::cout << testMatrix.rowdim() << " " << testMatrix.coldim() << " " << testMatrix.nnz() << std::endl;
*/

	commentator.start("ZeroOne matrix blackbox test suite", "ZeroOne");

  pass = pass && testBlackbox(testMatrix);

  delete [] rows;
  delete [] cols;

	commentator.stop("ZeroOne matrix blackbox test suite");
  return pass ? 0 : -1;
}
<commit_msg>Fix the "uninitialized" bug<commit_after>#include <iostream>
#include <vector>
#include <utility>

#include "linbox/blackbox/zero-one.h"
#include "linbox/field/modular.h"

#include "test-common.h"
#include "test-generic.h"

int main(int argc, char **argv) {
  bool pass = true;
  uint32 prime = 31337;
  size_t *rows, *cols, i;
  static size_t n = 1000, iter = 1;

  static Argument args[] = {
    { 'n', "-n N", "Set dimension of test matrix to NxN.", TYPE_INT, &n },
    { 'q', "-q Q", "Operate over the \"field\" GF(Q) [1].", TYPE_INT, &prime },
    { 'i', "-i I", "Perform each test for I iterations.", TYPE_INT, &iter},
	{ '\0' }
  };

  parseArguments(argc, argv, args);

  typedef LinBox::ZeroOne<LinBox::Modular<LinBox::uint32> > Matrix;

  LinBox::Modular<LinBox::uint32> afield(prime);

  rows = new size_t[3 * n];
  cols = new size_t[3 * n];

  // "arrow" matrix
  for(i = 0; i < n; i++) { rows[i] = 0; cols[i] = i; } // first row
  for(i = 0; i < n; i++) { rows[n+i] = i; cols[n+i] = 0; } // first col
  for(i = 0; i < n; i++) { rows[2*n+i] = i; cols[2*n+i] = i; } // diag
  Matrix testMatrix(afield, rows, cols, n, n, 3*n - 2);

  /*
  for(i = 0; i < n; i++) { rows[i] = i; cols[i] = i; } // diag
  Matrix testMatrix(afield, rows, cols, n, n, n);
  */
/*
  Matrix testMatrix(afield);
  ifstream mat_in("data/n4c6.b9.186558x198895.sms");
  testMatrix.read(mat_in);
  std::cout << testMatrix.rowdim() << " " << testMatrix.coldim() << " " << testMatrix.nnz() << std::endl;
*/

	commentator.start("ZeroOne matrix blackbox test suite", "ZeroOne");

  pass = pass && testBlackbox(testMatrix);

  delete [] rows;
  delete [] cols;

	commentator.stop("ZeroOne matrix blackbox test suite");
  return pass ? 0 : -1;
}
<|endoftext|>


<commit_before>#pragma once

#include <cassert>
#include <user-thread-debug.hpp>

#include "thread-data.hpp"
#include "../stack-address-tools.hpp"
#include "../splitstackapi.h"
#include "../mysetjmp.h"

namespace orks {
namespace userthread {
namespace detail {
namespace baddesign {
namespace splitstack {

using namespace stacktool;

class ThreadData {
    using Context = ThreadData*;
    struct SplitstackContext {
        splitstack_context ctx;
    };

public:
    context env;
    ThreadState state = ThreadState::before_launch;

    ThreadData* pass_on_longjmp = 0;
    void* transferred_data = nullptr;

private:
    Context(*func)(void* arg, Context prev);
    void* arg;

    SplitstackContext splitstack_context_;
    void* stack = nullptr;
    std::size_t stack_size = 0;

public:

    template <typename Fn>
    ThreadData(Fn fn)
        : ThreadData((Context(*)(void*, Context)) & (exec_thread_delete<Fn>),
                     (void*)(new Fn(std::move(fn)))) {

    }

    ThreadData(Context(*func)(void* arg, Context prev), void* arg)
        : func(func)
        , arg(arg) {

    }

    Context call_func(Context prev) {
        return func(arg, prev);
    }

    // always_inline for no split stack
    __attribute__((always_inline))
    void restore_extra_context() {
        __splitstack_setcontext(splitstack_context_.ctx);
    }

    // always_inline for no split stack
    __attribute__((always_inline))
    void save_extra_context() {
        __splitstack_getcontext(splitstack_context_.ctx);
    }

    // always_inline for no split stack
    __attribute__((always_inline))
    void initialize_extra_context_at_entry_point() {
        __stack_split_initialize();

        void* bottom = get_stack() + get_stack_size();
        void* split_stacks_boundary = __morestack_get_guard();

        debug::printf("stack top of new thread: %p, stack size of new thread: 0x%lx\n", get_stack(),
                      static_cast<unsigned long>(get_stack_size()));
        debug::printf("stack bottom of new thread: %p, stack boundary of new thread: %p\n", bottom, split_stacks_boundary);
        assert(more_forward_than(split_stacks_boundary, bottom));
    }

    char* get_stack() {
        return static_cast<char*>(stack);
    }

    std::size_t get_stack_size() {
        return stack_size;
    }

    // non copyable
    ThreadData(const ThreadData&) = delete;
    ThreadData(ThreadData&&) = delete;

    // this function is public
    // this is bad
    template <typename Fn>
    static ThreadData* create(Fn fn) {
        SplitstackContext ssctx;
        std::size_t size;
        void* stack = __splitstack_makecontext(SimpleStackAllocator::stack_size, ssctx.ctx, &size);
        assert(size != 0);
        auto th = new(stack) ThreadData(fn);
        th->splitstack_context_ = ssctx;
        th->stack = stack;
        th->stack_size = size;
        assert(th->get_stack_size() != 0);
        return th;

    }

    // this function is public
    // this is bad
    static void destroy(ThreadData& t) {
        SplitstackContext ssctx = t.splitstack_context_;
        t.~ThreadData();
        __splitstack_releasecontext(ssctx.ctx);

    }

private:
    template<typename Fn>
    static Context exec_thread_delete(void* func_obj, Context t) {
        Context r = (*static_cast<Fn*>(func_obj))(t);
        delete static_cast<Fn*>(func_obj);
        return r;
    }

};
}
}
}
}
}<commit_msg>Fix the bug of not used allocated split stack context<commit_after>#pragma once

#include <cassert>
#include <user-thread-debug.hpp>

#include "thread-data.hpp"
#include "../stack-address-tools.hpp"
#include "../splitstackapi.h"
#include "../mysetjmp.h"

namespace orks {
namespace userthread {
namespace detail {
namespace baddesign {
namespace splitstack {

using namespace stacktool;

class ThreadData {
    using Context = ThreadData*;
    struct SplitstackContext {
        splitstack_context ctx;
    };

public:
    context env;
    ThreadState state = ThreadState::before_launch;

    ThreadData* pass_on_longjmp = 0;
    void* transferred_data = nullptr;

private:
    Context(*func)(void* arg, Context prev);
    void* arg;

    SplitstackContext splitstack_context_;
    void* stack = nullptr;
    std::size_t stack_size = 0;

public:

    template <typename Fn>
    ThreadData(Fn fn)
        : ThreadData((Context(*)(void*, Context)) & (exec_thread_delete<Fn>),
                     (void*)(new Fn(std::move(fn)))) {

    }

    ThreadData(Context(*func)(void* arg, Context prev), void* arg)
        : func(func)
        , arg(arg) {

    }

    Context call_func(Context prev) {
        return func(arg, prev);
    }

    // always_inline for no split stack
    __attribute__((always_inline))
    void restore_extra_context() {
        __splitstack_setcontext(splitstack_context_.ctx);
    }

    // always_inline for no split stack
    __attribute__((always_inline))
    void save_extra_context() {
        __splitstack_getcontext(splitstack_context_.ctx);
    }

    // always_inline for no split stack
    __attribute__((always_inline))
    void initialize_extra_context_at_entry_point() {
        __splitstack_setcontext(splitstack_context_.ctx);

        void* bottom = get_stack() + get_stack_size();
        void* split_stacks_boundary = __morestack_get_guard();

        debug::printf("stack top of new thread: %p, stack size of new thread: 0x%lx\n", get_stack(),
                      static_cast<unsigned long>(get_stack_size()));
        debug::printf("stack bottom of new thread: %p, stack boundary of new thread: %p\n", bottom, split_stacks_boundary);
        assert(more_forward_than(split_stacks_boundary, bottom));
    }

    char* get_stack() {
        return static_cast<char*>(stack);
    }

    std::size_t get_stack_size() {
        return stack_size;
    }

    // non copyable
    ThreadData(const ThreadData&) = delete;
    ThreadData(ThreadData&&) = delete;

    // this function is public
    // this is bad
    template <typename Fn>
    static ThreadData* create(Fn fn) {
        SplitstackContext ssctx;
        std::size_t size;
        void* stack = __splitstack_makecontext(SimpleStackAllocator::stack_size, ssctx.ctx, &size);
        assert(size != 0);
        auto th = new(stack) ThreadData(fn);
        th->splitstack_context_ = ssctx;
        th->stack = stack;
        th->stack_size = size;
        assert(th->get_stack_size() != 0);
        return th;

    }

    // this function is public
    // this is bad
    static void destroy(ThreadData& t) {
        SplitstackContext ssctx = t.splitstack_context_;
        t.~ThreadData();
        __splitstack_releasecontext(ssctx.ctx);

    }

private:
    template<typename Fn>
    static Context exec_thread_delete(void* func_obj, Context t) {
        Context r = (*static_cast<Fn*>(func_obj))(t);
        delete static_cast<Fn*>(func_obj);
        return r;
    }

};
}
}
}
}
}<|endoftext|>


<commit_before>/*
Copyright libCellML Contributors

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 "utilities.h"

#include "libcellml/importsource.h"
#include "libcellml/model.h"
#include "libcellml/units.h"

#include <algorithm>
#include <cassert>
#include <cmath>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>

namespace libcellml {

/**
 * @brief Map Prefix to their string forms.
 *
 * An internal map used to convert a Prefix into its string form.
 */
static const std::map<Prefix, const std::string> prefixToString = {
    {Prefix::ATTO, "atto"},
    {Prefix::CENTI, "centi"},
    {Prefix::DECA, "deca"},
    {Prefix::DECI, "deci"},
    {Prefix::EXA, "exa"},
    {Prefix::FEMTO, "femto"},
    {Prefix::GIGA, "giga"},
    {Prefix::HECTO, "hecto"},
    {Prefix::KILO, "kilo"},
    {Prefix::MEGA, "mega"},
    {Prefix::MICRO, "micro"},
    {Prefix::MILLI, "milli"},
    {Prefix::NANO, "nano"},
    {Prefix::PETA, "peta"},
    {Prefix::PICO, "pico"},
    {Prefix::TERA, "tera"},
    {Prefix::YOCTO, "yocto"},
    {Prefix::YOTTA, "yotta"},
    {Prefix::ZEPTO, "zepto"},
    {Prefix::ZETTA, "zetta"}};

/**
 * @brief Map StandardUnit to their string forms.
 *
 * An internal map used to convert a standard unit into its string form.
 */
static const std::map<Units::StandardUnit, const std::string> standardUnitToString = {
    {Units::StandardUnit::AMPERE, "ampere"},
    {Units::StandardUnit::BECQUEREL, "becquerel"},
    {Units::StandardUnit::CANDELA, "candela"},
    {Units::StandardUnit::COULOMB, "coulomb"},
    {Units::StandardUnit::DIMENSIONLESS, "dimensionless"},
    {Units::StandardUnit::FARAD, "farad"},
    {Units::StandardUnit::GRAM, "gram"},
    {Units::StandardUnit::GRAY, "gray"},
    {Units::StandardUnit::HENRY, "henry"},
    {Units::StandardUnit::HERTZ, "hertz"},
    {Units::StandardUnit::JOULE, "joule"},
    {Units::StandardUnit::KATAL, "katal"},
    {Units::StandardUnit::KELVIN, "kelvin"},
    {Units::StandardUnit::KILOGRAM, "kilogram"},
    {Units::StandardUnit::LITRE, "litre"},
    {Units::StandardUnit::LUMEN, "lumen"},
    {Units::StandardUnit::LUX, "lux"},
    {Units::StandardUnit::METRE, "metre"},
    {Units::StandardUnit::MOLE, "mole"},
    {Units::StandardUnit::NEWTON, "newton"},
    {Units::StandardUnit::OHM, "ohm"},
    {Units::StandardUnit::PASCAL, "pascal"},
    {Units::StandardUnit::RADIAN, "radian"},
    {Units::StandardUnit::SECOND, "second"},
    {Units::StandardUnit::SIEMENS, "siemens"},
    {Units::StandardUnit::SIEVERT, "sievert"},
    {Units::StandardUnit::STERADIAN, "steradian"},
    {Units::StandardUnit::TESLA, "tesla"},
    {Units::StandardUnit::VOLT, "volt"},
    {Units::StandardUnit::WATT, "watt"},
    {Units::StandardUnit::WEBER, "weber"}};

/**
 * @brief The Unit struct.
 *
 * An internal structure to capture a unit definition.  The
 * prefix can be expressed using either an integer or an enum.
 * The enum structure member is given preference if both are set.
 */
struct Unit
{
    std::string mReference; /**< Reference to the units for the unit.*/
    std::string mPrefix; /**< String expression of the prefix for the unit.*/
    std::string mExponent; /**< Exponent for the unit.*/
    std::string mMultiplier; /**< Multiplier for the unit.*/
    std::string mId; /**< Id for the unit.*/
};

/**
 * @brief The Units::UnitsImpl struct.
 *
 * The private implementation for the Units class.
 */
struct Units::UnitsImpl
{
    std::vector<Unit> mUnits; /**< A vector of unit defined for this Units.*/

    std::vector<Unit>::iterator findUnit(const std::string &reference);
};

std::vector<Unit>::iterator Units::UnitsImpl::findUnit(const std::string &reference)
{
    return std::find_if(mUnits.begin(), mUnits.end(),
                        [=](const Unit &u) -> bool { return u.mReference == reference; });
}

/*

//TDOD: This code is progress towards checking that units are compatible.
using UnitMultiplierMap = std::map<std::string, double>;

    UnitMultiplierMap unitMap = {};
    for (const auto &baseUnits : baseUnitsList) {
        unitMap[baseUnits] = 0.0;
    }
bool updateUnitMultipliers(UnitMultiplierMap &unitMultiplierMap,
                           double &multiplier,
                           const UnitsPtr &units,
                           double uExp, double logMult,
                           int direction)
{
    bool updated = false;
    auto unitsName = units->name();
    if (!units->isBaseUnit()) {
        std::string ref;
        std::string pre;
        std::string id;
        double exp;
        double mult;
        double expMult;
        for (size_t i = 0; i < units->unitCount(); ++i) {
            units->unitAttributes(i, ref, pre, exp, expMult, id);
            mult = std::log10(expMult);
            if (!isStandardUnitName(ref)) {
                auto model = owningModel(units);
                auto refUnits = model->units(ref);
                updated = updateUnitMultipliers(unitMultiplierMap, multiplier, refUnits, exp * uExp, logMult + mult * uExp + standardPrefixList.at(pre) * uExp, direction);
            } else {
                for (const auto &iter : standardUnitsList.at(ref)) {
                    unitMultiplierMap.at(iter.first) += direction * (iter.second * exp * uExp);
                }
                multiplier += direction * (logMult + (standardMultiplierList.at(ref) + mult + standardPrefixList.at(pre)) * exp);
            }
        }
    } else if (unitMultiplierMap.find(unitsName) == unitMultiplierMap.end()) {
        unitMultiplierMap.emplace(std::pair<std::string, double>(unitsName, direction * uExp));
        multiplier += direction * logMult;
        updated = true;
    } else if (isStandardUnitName(unitsName)) {
        for (const auto &iter : standardUnitsList.at(unitsName)) {
            unitMultiplierMap.at(iter.first) += direction * (iter.second * uExp);
        }
        multiplier += direction * logMult;
        multiplier += direction * standardMultiplierList.at(unitsName);
        updated = true;
    }

    return updated;
}
*/

bool updateUnitMultipliers(double &multiplier,
                           const UnitsPtr &units,
                           double uExp, double logMult,
                           int direction)
{
    bool updated = false;
    auto unitsName = units->name();
    if (units->isBaseUnit()) {
        multiplier += direction * logMult;
        updated = true;
    } else {
        std::string ref;
        std::string pre;
        std::string id;
        double exp;
        double mult;
        double expMult;
        for (size_t i = 0; i < units->unitCount(); ++i) {
            units->unitAttributes(i, ref, pre, exp, expMult, id);
            mult = std::log10(expMult);
            if (isStandardUnitName(ref)) {
                multiplier += direction * (logMult + (standardMultiplierList.at(ref) + mult + standardPrefixList.at(pre)) * exp);
            } else {
                auto model = owningModel(units);
                auto refUnits = model->units(ref);
                updated = updateUnitMultipliers(multiplier, refUnits, exp * uExp, logMult + mult * uExp + standardPrefixList.at(pre) * uExp, direction);
            }
        }
    }

    return updated;
}

Units::Units()
    : mPimpl(new UnitsImpl())
{
}

Units::Units(const std::string &name)
    : mPimpl(new UnitsImpl())
{
    setName(name);
}

Units::~Units()
{
    delete mPimpl;
}

bool Units::isBaseUnit() const
{
    return unitCount() == 0;
}

void Units::addUnit(const std::string &reference, const std::string &prefix, double exponent,
                    double multiplier, const std::string &id)
{
    Unit u;
    u.mReference = reference;
    // Allow all nonzero user-specified prefixes
    try {
        int prefixInteger = std::stoi(prefix);
        if (prefixInteger != 0.0) {
            u.mPrefix = prefix;
        }
    } catch (std::invalid_argument &) {
        u.mPrefix = prefix;
    } catch (std::out_of_range &) {
        u.mPrefix = prefix;
    }
    if (exponent != 1.0) {
        u.mExponent = convertToString(exponent);
    }
    if (multiplier != 1.0) {
        u.mMultiplier = convertToString(multiplier);
    }
    if (!id.empty()) {
        u.mId = id;
    }
    mPimpl->mUnits.push_back(u);
}

void Units::addUnit(const std::string &reference, Prefix prefix, double exponent,
                    double multiplier, const std::string &id)
{
    auto search = prefixToString.find(prefix);
    const std::string prefixString = search->second;
    addUnit(reference, prefixString, exponent, multiplier, id);
}

void Units::addUnit(const std::string &reference, int prefix, double exponent,
                    double multiplier, const std::string &id)
{
    const std::string prefixString = convertToString(prefix);
    addUnit(reference, prefixString, exponent, multiplier, id);
}

void Units::addUnit(const std::string &reference, double exponent, const std::string &id)
{
    addUnit(reference, "0", exponent, 1.0, id);
}

void Units::addUnit(const std::string &reference)
{
    addUnit(reference, "0", 1.0, 1.0, "");
}

void Units::addUnit(StandardUnit standardRef, const std::string &prefix, double exponent,
                    double multiplier, const std::string &id)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    addUnit(reference, prefix, exponent, multiplier, id);
}

void Units::addUnit(StandardUnit standardRef, Prefix prefix, double exponent,
                    double multiplier, const std::string &id)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    const std::string prefixString = prefixToString.find(prefix)->second;
    addUnit(reference, prefixString, exponent, multiplier, id);
}

void Units::addUnit(StandardUnit standardRef, int prefix, double exponent,
                    double multiplier, const std::string &id)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    const std::string prefixString = convertToString(prefix);
    addUnit(reference, prefixString, exponent, multiplier, id);
}

void Units::addUnit(StandardUnit standardRef, double exponent, const std::string &id)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    addUnit(reference, "0", exponent, 1.0, id);
}

void Units::addUnit(StandardUnit standardRef)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    addUnit(reference, "0", 1.0, 1.0, "");
}

void Units::unitAttributes(StandardUnit standardRef, std::string &prefix, double &exponent, double &multiplier, std::string &id) const
{
    std::string dummyReference;
    const std::string reference = standardUnitToString.find(standardRef)->second;
    auto result = mPimpl->findUnit(reference);
    unitAttributes(size_t(result - mPimpl->mUnits.begin()), dummyReference, prefix, exponent, multiplier, id);
}

void Units::unitAttributes(const std::string &reference, std::string &prefix, double &exponent, double &multiplier, std::string &id) const
{
    std::string dummyReference;
    auto result = mPimpl->findUnit(reference);
    unitAttributes(size_t(result - mPimpl->mUnits.begin()), dummyReference, prefix, exponent, multiplier, id);
}

void Units::unitAttributes(size_t index, std::string &reference, std::string &prefix, double &exponent, double &multiplier, std::string &id) const
{
    Unit u;
    if (index < mPimpl->mUnits.size()) {
        u = mPimpl->mUnits.at(index);
    }
    reference = u.mReference;
    prefix = u.mPrefix;
    if (!u.mExponent.empty()) {
        exponent = std::stod(u.mExponent);
    } else {
        exponent = 1.0;
    }
    if (!u.mMultiplier.empty()) {
        multiplier = std::stod(u.mMultiplier);
    } else {
        multiplier = 1.0;
    }
    id = u.mId;
}

bool Units::removeUnit(const std::string &reference)
{
    bool status = false;
    auto result = mPimpl->findUnit(reference);
    if (result != mPimpl->mUnits.end()) {
        mPimpl->mUnits.erase(result);
        status = true;
    }

    return status;
}

bool Units::removeUnit(size_t index)
{
    bool status = false;
    if (index < mPimpl->mUnits.size()) {
        mPimpl->mUnits.erase(mPimpl->mUnits.begin() + int64_t(index));
        status = true;
    }

    return status;
}

bool Units::removeUnit(StandardUnit standardRef)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    return removeUnit(reference);
}

void Units::removeAllUnits()
{
    mPimpl->mUnits.clear();
}

void Units::setSourceUnits(const ImportSourcePtr &importSource, const std::string &name)
{
    setImportSource(importSource);
    setImportReference(name);
}

size_t Units::unitCount() const
{
    return mPimpl->mUnits.size();
}

double Units::scalingFactor(const UnitsPtr &units1, const UnitsPtr &units2)
{
    double multiplier = 0.0;
    double scalingFactor = 0.0;

	if (!units1 || !units2) {
		// no change
	} else {
        updateUnitMultipliers(multiplier, units2, 1, 0, 1);
        updateUnitMultipliers(multiplier, units1, 1, 0, -1);
        scalingFactor = std::pow(10, multiplier);
	}

    return scalingFactor;
}

} // namespace libcellml
<commit_msg>Fixed formatting issues in scalingFactor<commit_after>/*
Copyright libCellML Contributors

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 "utilities.h"

#include "libcellml/importsource.h"
#include "libcellml/model.h"
#include "libcellml/units.h"

#include <algorithm>
#include <cassert>
#include <cmath>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>

namespace libcellml {

/**
 * @brief Map Prefix to their string forms.
 *
 * An internal map used to convert a Prefix into its string form.
 */
static const std::map<Prefix, const std::string> prefixToString = {
    {Prefix::ATTO, "atto"},
    {Prefix::CENTI, "centi"},
    {Prefix::DECA, "deca"},
    {Prefix::DECI, "deci"},
    {Prefix::EXA, "exa"},
    {Prefix::FEMTO, "femto"},
    {Prefix::GIGA, "giga"},
    {Prefix::HECTO, "hecto"},
    {Prefix::KILO, "kilo"},
    {Prefix::MEGA, "mega"},
    {Prefix::MICRO, "micro"},
    {Prefix::MILLI, "milli"},
    {Prefix::NANO, "nano"},
    {Prefix::PETA, "peta"},
    {Prefix::PICO, "pico"},
    {Prefix::TERA, "tera"},
    {Prefix::YOCTO, "yocto"},
    {Prefix::YOTTA, "yotta"},
    {Prefix::ZEPTO, "zepto"},
    {Prefix::ZETTA, "zetta"}};

/**
 * @brief Map StandardUnit to their string forms.
 *
 * An internal map used to convert a standard unit into its string form.
 */
static const std::map<Units::StandardUnit, const std::string> standardUnitToString = {
    {Units::StandardUnit::AMPERE, "ampere"},
    {Units::StandardUnit::BECQUEREL, "becquerel"},
    {Units::StandardUnit::CANDELA, "candela"},
    {Units::StandardUnit::COULOMB, "coulomb"},
    {Units::StandardUnit::DIMENSIONLESS, "dimensionless"},
    {Units::StandardUnit::FARAD, "farad"},
    {Units::StandardUnit::GRAM, "gram"},
    {Units::StandardUnit::GRAY, "gray"},
    {Units::StandardUnit::HENRY, "henry"},
    {Units::StandardUnit::HERTZ, "hertz"},
    {Units::StandardUnit::JOULE, "joule"},
    {Units::StandardUnit::KATAL, "katal"},
    {Units::StandardUnit::KELVIN, "kelvin"},
    {Units::StandardUnit::KILOGRAM, "kilogram"},
    {Units::StandardUnit::LITRE, "litre"},
    {Units::StandardUnit::LUMEN, "lumen"},
    {Units::StandardUnit::LUX, "lux"},
    {Units::StandardUnit::METRE, "metre"},
    {Units::StandardUnit::MOLE, "mole"},
    {Units::StandardUnit::NEWTON, "newton"},
    {Units::StandardUnit::OHM, "ohm"},
    {Units::StandardUnit::PASCAL, "pascal"},
    {Units::StandardUnit::RADIAN, "radian"},
    {Units::StandardUnit::SECOND, "second"},
    {Units::StandardUnit::SIEMENS, "siemens"},
    {Units::StandardUnit::SIEVERT, "sievert"},
    {Units::StandardUnit::STERADIAN, "steradian"},
    {Units::StandardUnit::TESLA, "tesla"},
    {Units::StandardUnit::VOLT, "volt"},
    {Units::StandardUnit::WATT, "watt"},
    {Units::StandardUnit::WEBER, "weber"}};

/**
 * @brief The Unit struct.
 *
 * An internal structure to capture a unit definition.  The
 * prefix can be expressed using either an integer or an enum.
 * The enum structure member is given preference if both are set.
 */
struct Unit
{
    std::string mReference; /**< Reference to the units for the unit.*/
    std::string mPrefix; /**< String expression of the prefix for the unit.*/
    std::string mExponent; /**< Exponent for the unit.*/
    std::string mMultiplier; /**< Multiplier for the unit.*/
    std::string mId; /**< Id for the unit.*/
};

/**
 * @brief The Units::UnitsImpl struct.
 *
 * The private implementation for the Units class.
 */
struct Units::UnitsImpl
{
    std::vector<Unit> mUnits; /**< A vector of unit defined for this Units.*/

    std::vector<Unit>::iterator findUnit(const std::string &reference);
};

std::vector<Unit>::iterator Units::UnitsImpl::findUnit(const std::string &reference)
{
    return std::find_if(mUnits.begin(), mUnits.end(),
                        [=](const Unit &u) -> bool { return u.mReference == reference; });
}

/*

//TDOD: This code is progress towards checking that units are compatible.
using UnitMultiplierMap = std::map<std::string, double>;

    UnitMultiplierMap unitMap = {};
    for (const auto &baseUnits : baseUnitsList) {
        unitMap[baseUnits] = 0.0;
    }
bool updateUnitMultipliers(UnitMultiplierMap &unitMultiplierMap,
                           double &multiplier,
                           const UnitsPtr &units,
                           double uExp, double logMult,
                           int direction)
{
    bool updated = false;
    auto unitsName = units->name();
    if (!units->isBaseUnit()) {
        std::string ref;
        std::string pre;
        std::string id;
        double exp;
        double mult;
        double expMult;
        for (size_t i = 0; i < units->unitCount(); ++i) {
            units->unitAttributes(i, ref, pre, exp, expMult, id);
            mult = std::log10(expMult);
            if (!isStandardUnitName(ref)) {
                auto model = owningModel(units);
                auto refUnits = model->units(ref);
                updated = updateUnitMultipliers(unitMultiplierMap, multiplier, refUnits, exp * uExp, logMult + mult * uExp + standardPrefixList.at(pre) * uExp, direction);
            } else {
                for (const auto &iter : standardUnitsList.at(ref)) {
                    unitMultiplierMap.at(iter.first) += direction * (iter.second * exp * uExp);
                }
                multiplier += direction * (logMult + (standardMultiplierList.at(ref) + mult + standardPrefixList.at(pre)) * exp);
            }
        }
    } else if (unitMultiplierMap.find(unitsName) == unitMultiplierMap.end()) {
        unitMultiplierMap.emplace(std::pair<std::string, double>(unitsName, direction * uExp));
        multiplier += direction * logMult;
        updated = true;
    } else if (isStandardUnitName(unitsName)) {
        for (const auto &iter : standardUnitsList.at(unitsName)) {
            unitMultiplierMap.at(iter.first) += direction * (iter.second * uExp);
        }
        multiplier += direction * logMult;
        multiplier += direction * standardMultiplierList.at(unitsName);
        updated = true;
    }

    return updated;
}
*/

bool updateUnitMultipliers(double &multiplier,
                           const UnitsPtr &units,
                           double uExp, double logMult,
                           int direction)
{
    bool updated = false;
    auto unitsName = units->name();
    if (units->isBaseUnit()) {
        multiplier += direction * logMult;
        updated = true;
    } else {
        std::string ref;
        std::string pre;
        std::string id;
        double exp;
        double mult;
        double expMult;
        for (size_t i = 0; i < units->unitCount(); ++i) {
            units->unitAttributes(i, ref, pre, exp, expMult, id);
            mult = std::log10(expMult);
            if (isStandardUnitName(ref)) {
                multiplier += direction * (logMult + (standardMultiplierList.at(ref) + mult + standardPrefixList.at(pre)) * exp);
            } else {
                auto model = owningModel(units);
                auto refUnits = model->units(ref);
                updated = updateUnitMultipliers(multiplier, refUnits, exp * uExp, logMult + mult * uExp + standardPrefixList.at(pre) * uExp, direction);
            }
        }
    }

    return updated;
}

Units::Units()
    : mPimpl(new UnitsImpl())
{
}

Units::Units(const std::string &name)
    : mPimpl(new UnitsImpl())
{
    setName(name);
}

Units::~Units()
{
    delete mPimpl;
}

bool Units::isBaseUnit() const
{
    return unitCount() == 0;
}

void Units::addUnit(const std::string &reference, const std::string &prefix, double exponent,
                    double multiplier, const std::string &id)
{
    Unit u;
    u.mReference = reference;
    // Allow all nonzero user-specified prefixes
    try {
        int prefixInteger = std::stoi(prefix);
        if (prefixInteger != 0.0) {
            u.mPrefix = prefix;
        }
    } catch (std::invalid_argument &) {
        u.mPrefix = prefix;
    } catch (std::out_of_range &) {
        u.mPrefix = prefix;
    }
    if (exponent != 1.0) {
        u.mExponent = convertToString(exponent);
    }
    if (multiplier != 1.0) {
        u.mMultiplier = convertToString(multiplier);
    }
    if (!id.empty()) {
        u.mId = id;
    }
    mPimpl->mUnits.push_back(u);
}

void Units::addUnit(const std::string &reference, Prefix prefix, double exponent,
                    double multiplier, const std::string &id)
{
    auto search = prefixToString.find(prefix);
    const std::string prefixString = search->second;
    addUnit(reference, prefixString, exponent, multiplier, id);
}

void Units::addUnit(const std::string &reference, int prefix, double exponent,
                    double multiplier, const std::string &id)
{
    const std::string prefixString = convertToString(prefix);
    addUnit(reference, prefixString, exponent, multiplier, id);
}

void Units::addUnit(const std::string &reference, double exponent, const std::string &id)
{
    addUnit(reference, "0", exponent, 1.0, id);
}

void Units::addUnit(const std::string &reference)
{
    addUnit(reference, "0", 1.0, 1.0, "");
}

void Units::addUnit(StandardUnit standardRef, const std::string &prefix, double exponent,
                    double multiplier, const std::string &id)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    addUnit(reference, prefix, exponent, multiplier, id);
}

void Units::addUnit(StandardUnit standardRef, Prefix prefix, double exponent,
                    double multiplier, const std::string &id)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    const std::string prefixString = prefixToString.find(prefix)->second;
    addUnit(reference, prefixString, exponent, multiplier, id);
}

void Units::addUnit(StandardUnit standardRef, int prefix, double exponent,
                    double multiplier, const std::string &id)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    const std::string prefixString = convertToString(prefix);
    addUnit(reference, prefixString, exponent, multiplier, id);
}

void Units::addUnit(StandardUnit standardRef, double exponent, const std::string &id)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    addUnit(reference, "0", exponent, 1.0, id);
}

void Units::addUnit(StandardUnit standardRef)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    addUnit(reference, "0", 1.0, 1.0, "");
}

void Units::unitAttributes(StandardUnit standardRef, std::string &prefix, double &exponent, double &multiplier, std::string &id) const
{
    std::string dummyReference;
    const std::string reference = standardUnitToString.find(standardRef)->second;
    auto result = mPimpl->findUnit(reference);
    unitAttributes(size_t(result - mPimpl->mUnits.begin()), dummyReference, prefix, exponent, multiplier, id);
}

void Units::unitAttributes(const std::string &reference, std::string &prefix, double &exponent, double &multiplier, std::string &id) const
{
    std::string dummyReference;
    auto result = mPimpl->findUnit(reference);
    unitAttributes(size_t(result - mPimpl->mUnits.begin()), dummyReference, prefix, exponent, multiplier, id);
}

void Units::unitAttributes(size_t index, std::string &reference, std::string &prefix, double &exponent, double &multiplier, std::string &id) const
{
    Unit u;
    if (index < mPimpl->mUnits.size()) {
        u = mPimpl->mUnits.at(index);
    }
    reference = u.mReference;
    prefix = u.mPrefix;
    if (!u.mExponent.empty()) {
        exponent = std::stod(u.mExponent);
    } else {
        exponent = 1.0;
    }
    if (!u.mMultiplier.empty()) {
        multiplier = std::stod(u.mMultiplier);
    } else {
        multiplier = 1.0;
    }
    id = u.mId;
}

bool Units::removeUnit(const std::string &reference)
{
    bool status = false;
    auto result = mPimpl->findUnit(reference);
    if (result != mPimpl->mUnits.end()) {
        mPimpl->mUnits.erase(result);
        status = true;
    }

    return status;
}

bool Units::removeUnit(size_t index)
{
    bool status = false;
    if (index < mPimpl->mUnits.size()) {
        mPimpl->mUnits.erase(mPimpl->mUnits.begin() + int64_t(index));
        status = true;
    }

    return status;
}

bool Units::removeUnit(StandardUnit standardRef)
{
    const std::string reference = standardUnitToString.find(standardRef)->second;
    return removeUnit(reference);
}

void Units::removeAllUnits()
{
    mPimpl->mUnits.clear();
}

void Units::setSourceUnits(const ImportSourcePtr &importSource, const std::string &name)
{
    setImportSource(importSource);
    setImportReference(name);
}

size_t Units::unitCount() const
{
    return mPimpl->mUnits.size();
}

double Units::scalingFactor(const UnitsPtr &units1, const UnitsPtr &units2)
{
    double multiplier = 0.0;
    double scalingFactor = 0.0;

    if (!units1 || !units2) {
        // no change
    } else {
        updateUnitMultipliers(multiplier, units2, 1, 0, 1);
        updateUnitMultipliers(multiplier, units1, 1, 0, -1);
        scalingFactor = std::pow(10, multiplier);
    }

    return scalingFactor;
}

} // namespace libcellml
<|endoftext|>


<commit_before># include "utils.h"

using namespace std;

std::string readFile(const string &fileName)
{
	ifstream ifs(fileName.c_str(), ios::in | ios::binary | ios::ate);

	ifstream::pos_type fileSize = ifs.tellg();
	ifs.seekg(0, ios::beg);

	vector<char> bytes(fileSize);
	ifs.read(&bytes[0], fileSize);

	return string(&bytes[0], fileSize);
}

bool isFileExist(const char *fileName)
{
    std::ifstream infile(fileName);
    return infile.good();
}

bool setupLogger(const char* filename) {
	std::vector<spdlog::sink_ptr> sinks;
	sinks.push_back(make_shared<spdlog::sinks::daily_file_sink_st>(filename, "txt", 0, 0));
#ifdef _MSC_VER
	sinks.push_back(make_shared<spdlog::sinks::wincolor_stdout_sink_st>());
#else
	sinks.push_back(make_shared<spdlog::sinks::stdout_sink_st>());
#endif
	auto logger = make_shared<spdlog::logger>("my_logger", begin(sinks), end(sinks));
	spdlog::register_logger(logger);
	logger->flush_on(spdlog::level::err);
	spdlog::set_pattern("[%D %H:%M:%S:%e][%l] %v");
	spdlog::set_level(spdlog::level::info);
	logger->set_level(spdlog::level::debug);
	logger->info("logger created successfully.");
	return true;
}

void debugDocument(const rapidjson::Document& d) {
	auto logger = spdlog::get("my_logger");
	rapidjson::StringBuffer buffer;
	rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
	d.Accept(writer);
	const char* s = buffer.GetString();
	logger->info(s);
}

void debugBytes(const char * msg, uint8_t* data, size_t len) {
	std::cout << msg << ":";
	for (int i = 0; i < len; i++) {
		std::cout << std::hex << (int)data[i] << std::dec << ",";
	}
	std::cout << std::endl;
}<commit_msg>no message<commit_after># include "utils.h"

using namespace std;

std::string readFile(const string &fileName)
{
	ifstream ifs(fileName.c_str(), ios::in | ios::binary | ios::ate);

	ifstream::pos_type fileSize = ifs.tellg();
	ifs.seekg(0, ios::beg);

	vector<char> bytes(fileSize);
	ifs.read(&bytes[0], fileSize);

	return string(&bytes[0], fileSize);
}

bool isFileExist(const char *fileName)
{
    std::ifstream infile(fileName);
    return infile.good();
}

bool setupLogger(const char* filename) {
	std::vector<spdlog::sink_ptr> sinks;
	sinks.push_back(make_shared<spdlog::sinks::rotating_file_sink_st>(filename, "txt", 1048576 * 5, 3));
	//sinks.push_back(make_shared<spdlog::sinks::daily_file_sink_st>(filename, "txt", 0, 0));
#ifdef _MSC_VER
	sinks.push_back(make_shared<spdlog::sinks::wincolor_stdout_sink_st>());
#else
	sinks.push_back(make_shared<spdlog::sinks::stdout_sink_st>());
#endif
	auto logger = make_shared<spdlog::logger>("my_logger", begin(sinks), end(sinks));
	spdlog::register_logger(logger);
	logger->flush_on(spdlog::level::err);
	spdlog::set_pattern("[%D %H:%M:%S:%e][%l] %v");
	spdlog::set_level(spdlog::level::info);
	logger->set_level(spdlog::level::debug);
	logger->info("logger created successfully.");
	return true;
}

void debugDocument(const rapidjson::Document& d) {
	auto logger = spdlog::get("my_logger");
	rapidjson::StringBuffer buffer;
	rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
	d.Accept(writer);
	const char* s = buffer.GetString();
	logger->info(s);
}

void debugBytes(const char * msg, uint8_t* data, size_t len) {
	std::cout << msg << ":";
	for (int i = 0; i < len; i++) {
		std::cout << std::hex << (int)data[i] << std::dec << ",";
	}
	std::cout << std::endl;
}<|endoftext|>


<commit_before>#ifndef LYZA_JSON_VALUE__
# define LYZA_JSON_VALUE__

# include <map>
# include <string>
# include <vector>
# include <sstream>

# include "fct/variant.hpp"

namespace lyza { namespace json {

class value {
	public:
		class null {};
		typedef bool boolean;
		typedef double number;
		typedef std::string string;
		typedef std::vector<value> array;
		typedef std::map<std::string, value> object;

	public:
		value()
			: var_(null())
		{
		}

	private:
		struct string_visitor {
			typedef std::string ret_type;

			ret_type operator()(null) const
			{
				return "null";
			}

			ret_type operator()(bool b) const
			{
				return b ? "true" : "false";
			}

			ret_type operator()(double d) const
			{
				std::ostringstream ss;

				ss << d;
				return ss.str();
			}

			ret_type operator()(std::string const& s) const
			{
				return "\"" + s + "\"";
			}

			ret_type operator()(std::vector<value> const& v) const
			{
				bool first = true;
				std::string acc;

				acc += "[";
				for (auto& it : v) {
					if (!first)
						acc += ",";
					else
						first = false;
					acc += it.to_string();
				}
				acc += "]";

				return acc;
			}

			ret_type operator()(std::map<std::string, value> const& m) const
			{
				bool first = true;
				std::string acc;

				acc += "{";
				for (auto& it : m) {
					if (!first)
						acc += ",";
					else
						first = false;
					acc += "\"" + it.first + "\"" + ":" + it.second.to_string();
				}
				acc += "}";

				return acc;
			}
		};

	public:
# define DEF_CTOR(T)\
		value(T const& t) : var_(t) { }\
		value(T&& t) : var_(std::move(t)) { }

		DEF_CTOR(null)
		DEF_CTOR(array)
		DEF_CTOR(string)
		DEF_CTOR(object)

		value(int i) : var_(static_cast<number>(i)) { }
		value(number d) : var_(d) { }
		value(boolean b) : var_(b) { }

		value(value const& v)
			: var_(v.var_)
		{
		}

		value(value&& v)
			: var_(std::move(v.var_))
		{
		}

	public:
# define DEF_OP(T)\
		value& operator=(T const& t) { var_ = t; return *this; }\
		value& operator=(T&& t) { var_ = std::move(t); return *this; }

		DEF_OP(null)
		DEF_OP(array)
		DEF_OP(string)
		DEF_OP(object)

		value& operator=(int i)
		{
			var_ = static_cast<number>(i);
			return *this;
		}

		value& operator=(number d)
		{
			var_ = d;
			return *this;
		}

		value& operator=(value const& v)
		{
			var_ = v.var_;
			return *this;
		}

		value& operator=(value&& v)
		{
			var_ = std::move(v.var_);
			return *this;
		}

	public:
		std::string to_string() const
		{
			return var_.apply_visitor(string_visitor());
		}

		static std::string to_string(value const& v)
		{
			return v.var_.apply_visitor(string_visitor());
		}

	public:
		typedef
			functional::variant<
				null,
				std::vector<value>,
				bool,
				std::string,
				number,
				std::map<std::string, value>
			> t;

	private:
		t var_;
};

typedef value::object object;
typedef value::boolean boolean;
typedef value::string string;
typedef value::number number;
typedef value::array array;
typedef value::null null;

}}

#endif
<commit_msg>Add const char* overload<commit_after>#ifndef LYZA_JSON_VALUE__
# define LYZA_JSON_VALUE__

# include <map>
# include <string>
# include <vector>
# include <sstream>

# include "fct/variant.hpp"

namespace lyza { namespace json {

class value {
	public:
		class null {};
		typedef bool boolean;
		typedef double number;
		typedef std::string string;
		typedef std::vector<value> array;
		typedef std::map<std::string, value> object;

	public:
		value()
			: var_(null())
		{
		}

	private:
		struct string_visitor {
			typedef std::string ret_type;

			ret_type operator()(null) const
			{
				return "null";
			}

			ret_type operator()(bool b) const
			{
				return b ? "true" : "false";
			}

			ret_type operator()(double d) const
			{
				std::ostringstream ss;

				ss << d;
				return ss.str();
			}

			ret_type operator()(std::string const& s) const
			{
				return "\"" + s + "\"";
			}

			ret_type operator()(std::vector<value> const& v) const
			{
				bool first = true;
				std::string acc;

				acc += "[";
				for (auto& it : v) {
					if (!first)
						acc += ",";
					else
						first = false;
					acc += it.to_string();
				}
				acc += "]";

				return acc;
			}

			ret_type operator()(std::map<std::string, value> const& m) const
			{
				bool first = true;
				std::string acc;

				acc += "{";
				for (auto& it : m) {
					if (!first)
						acc += ",";
					else
						first = false;
					acc += "\"" + it.first + "\"" + ":" + it.second.to_string();
				}
				acc += "}";

				return acc;
			}
		};

	public:
# define DEF_CTOR(T)\
		value(T const& t) : var_(t) { }\
		value(T&& t) : var_(std::move(t)) { }

		DEF_CTOR(null)
		DEF_CTOR(array)
		DEF_CTOR(string)
		DEF_CTOR(object)

		value(int i) : var_(static_cast<number>(i)) { }
		value(number d) : var_(d) { }
		value(boolean b) : var_(b) { }

		value(const char* s)
			: var_(string(s))
		{
		}

		value(value const& v)
			: var_(v.var_)
		{
		}

		value(value&& v)
			: var_(std::move(v.var_))
		{
		}

	public:
# define DEF_OP(T)\
		value& operator=(T const& t) { var_ = t; return *this; }\
		value& operator=(T&& t) { var_ = std::move(t); return *this; }

		DEF_OP(null)
		DEF_OP(array)
		DEF_OP(string)
		DEF_OP(object)

		value& operator=(int i)
		{
			var_ = static_cast<number>(i);
			return *this;
		}

		value& operator=(number d)
		{
			var_ = d;
			return *this;
		}

		value& operator=(const char* s)
		{
			var_ = string(s);
			return *this;
		}

		value& operator=(value const& v)
		{
			var_ = v.var_;
			return *this;
		}

		value& operator=(value&& v)
		{
			var_ = std::move(v.var_);
			return *this;
		}

	public:
		std::string to_string() const
		{
			return var_.apply_visitor(string_visitor());
		}

		static std::string to_string(value const& v)
		{
			return v.var_.apply_visitor(string_visitor());
		}

	public:
		typedef
			functional::variant<
				null,
				std::vector<value>,
				bool,
				std::string,
				number,
				std::map<std::string, value>
			> t;

	private:
		t var_;
};

typedef value::object object;
typedef value::boolean boolean;
typedef value::string string;
typedef value::number number;
typedef value::array array;
typedef value::null null;

}}

#endif
<|endoftext|>