<commit_before>// Copyright 2015 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "elang/lir/testing/lir_test.h"

#include "base/logging.h"
#include "elang/lir/transforms/parallel_copy_expander.h"

namespace elang {
namespace lir {
namespace {

//////////////////////////////////////////////////////////////////////
//
// LirParallelCopyExpanderTest
//
class LirParallelCopyExpanderTest : public testing::LirTest {
 protected:
  typedef std::pair<Value, Value> Task;

  LirParallelCopyExpanderTest() = default;
  ~LirParallelCopyExpanderTest() = default;

  static Value int32_type() {
    return Value(Value::Type::Integer, ValueSize::Size32);
  }

  static Value physical(int data) {
    return Value(Value::Type::Integer, ValueSize::Size32,
                 Value::Kind::PhysicalRegister, data);
  }

  static Value stack_slot(int data) {
    return Value(Value::Type::Integer, ValueSize::Size32,
                 Value::Kind::StackSlot, data);
  }

  void Expand(const std::vector<Task>& tasks, base::StringPiece expected);
  void ExpandWithScratch(const std::vector<Task>& tasks,
                         Value scratch,
                         base::StringPiece expected);
  void ExpandWithScratch2(const std::vector<Task>& tasks,
                          Value scratch1,
                          Value scratch2,
                          base::StringPiece expected);

 private:
  DISALLOW_COPY_AND_ASSIGN(LirParallelCopyExpanderTest);
};

void LirParallelCopyExpanderTest::Expand(const std::vector<Task>& tasks,
                                         base::StringPiece expected) {
  ExpandWithScratch2(tasks, Value(), Value(), expected);
}

void LirParallelCopyExpanderTest::ExpandWithScratch(
    const std::vector<Task>& tasks,
    Value scratch1,
    base::StringPiece expected) {
  ExpandWithScratch2(tasks, scratch1, Value(), expected);
}

void LirParallelCopyExpanderTest::ExpandWithScratch2(
    const std::vector<Task>& original_tasks,
    Value scratch1,
    Value scratch2,
    base::StringPiece expected) {
  auto tasks = original_tasks;
  DCHECK(!tasks.empty());
  for (auto count = 0u; count < tasks.size(); ++count) {
    ParallelCopyExpander expander(factory(), int32_type());
    for (auto task : tasks)
      expander.AddTask(task.first, task.second);
    if (scratch1.is_physical())
      expander.AddScratch(scratch1);
    if (scratch2.is_physical())
      expander.AddScratch(scratch2);

    std::stringstream ostream;
    for (auto const instr : expander.Expand())
      ostream << PrintAsGeneric(instr) << std::endl;
    EXPECT_EQ(expected, ostream.str());

    std::rotate(tasks.begin(), tasks.begin() + 1, tasks.end());
  }
}

// Test cases...

TEST_F(LirParallelCopyExpanderTest, AutoScratchByImmediate) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(2)),
       std::make_pair(stack_slot(1), physical(0)),
       std::make_pair(physical(1), Value::SmallInt32(42)),
      },
      "mov sp[1] = R0\n"
      "mov R1 = sp[2]\n"
      "mov sp[0] = R1\n"
      "mov R1 = #42\n");
}

TEST_F(LirParallelCopyExpanderTest, AutoScratchByMemory) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(2)),
       std::make_pair(stack_slot(1), physical(0)),
       std::make_pair(physical(1), stack_slot(2)),
      },
      "mov sp[1] = R0\n"
      "mov R1 = sp[2]\n"
      "mov sp[0] = R1\n");
}

TEST_F(LirParallelCopyExpanderTest, AutoScratchByMemory2) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(2)),
       std::make_pair(stack_slot(1), physical(0)),
       std::make_pair(physical(1), stack_slot(3)),
      },
      "mov sp[1] = R0\n"
      "mov R1 = sp[2]\n"
      "mov sp[0] = R1\n"
      "mov R1 = sp[3]\n");
}

TEST_F(LirParallelCopyExpanderTest, Basic) {
  Expand(
      {
       std::make_pair(physical(0), physical(1)),
       std::make_pair(physical(2), physical(1)),
       std::make_pair(physical(4), physical(3)),
      },
      "mov R0 = R1\n"
      "mov R2 = R1\n"
      "mov R4 = R3\n");
}

TEST_F(LirParallelCopyExpanderTest, MemorySwap) {
  ExpandWithScratch2(
      {
       std::make_pair(stack_slot(0), stack_slot(1)),
       std::make_pair(stack_slot(1), stack_slot(0)),
      },
      physical(2), physical(3),
      "mov R3 = sp[1]\n"
      "mov R2 = sp[0]\n"
      "mov sp[0] = R3\n"
      "mov sp[1] = R2\n");
}

// memory swap requires 2 scratch register
TEST_F(LirParallelCopyExpanderTest, MemorySwapNoScratch) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(1)),
       std::make_pair(stack_slot(1), stack_slot(0)),
      },
      "");
}

// memory swap requires 2 scratch register
TEST_F(LirParallelCopyExpanderTest, MemorySwapOneScratch) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(1)),
       std::make_pair(stack_slot(1), stack_slot(0)),
      },
      "");
}

TEST_F(LirParallelCopyExpanderTest, PhysicalToMemory) {
  Expand(
      {
       std::make_pair(stack_slot(0), physical(0)),
       std::make_pair(stack_slot(1), physical(1)),
      },
      "mov sp[0] = R0\n"
      "mov sp[1] = R1\n");
}

TEST_F(LirParallelCopyExpanderTest, Rotate) {
  Expand(
      {
       std::make_pair(physical(0), physical(1)),
       std::make_pair(physical(1), physical(2)),
       std::make_pair(physical(2), physical(0)),
      },
      "pcopy R0, R1 = R1, R0\n"
      "pcopy R1, R2 = R2, R1\n");
}

TEST_F(LirParallelCopyExpanderTest, RotateMemory) {
  ExpandWithScratch2(
      {
       std::make_pair(stack_slot(0), stack_slot(1)),
       std::make_pair(stack_slot(1), stack_slot(2)),
       std::make_pair(stack_slot(2), stack_slot(0)),
      },
      physical(4), physical(5),
      "mov R5 = sp[1]\n"
      "mov R4 = sp[0]\n"
      "mov sp[0] = R5\n"
      "mov R5 = sp[2]\n"
      "mov sp[1] = R5\n"
      "mov sp[2] = R4\n");
}

TEST_F(LirParallelCopyExpanderTest, RotateMemoryAndPhysical) {
  ExpandWithScratch(
      {
       std::make_pair(physical(0), physical(1)),
       std::make_pair(physical(1), stack_slot(2)),
       std::make_pair(stack_slot(2), physical(0)),
      },
      physical(2),
      "mov R2 = sp[2]\n"
      "mov sp[2] = R0\n"
      "mov R0 = R1\n"
      "mov R1 = R2\n");
}

TEST_F(LirParallelCopyExpanderTest, Swap) {
  Expand(
      {
       std::make_pair(physical(0), physical(1)),
       std::make_pair(physical(1), physical(0)),
      },
      "pcopy R0, R1 = R1, R0\n");
}

}  // namespace
}  // namespace lir
}  // namespace elang
<commit_msg>elang/lir/transforms: Use permutation rather than rotation for test case in |LirParallelCopyExpanderTest|.<commit_after>// Copyright 2015 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "elang/lir/testing/lir_test.h"

#include "base/logging.h"
#include "elang/lir/transforms/parallel_copy_expander.h"

namespace elang {
namespace lir {
namespace {

//////////////////////////////////////////////////////////////////////
//
// LirParallelCopyExpanderTest
//
class LirParallelCopyExpanderTest : public testing::LirTest {
 protected:
  typedef std::pair<Value, Value> Task;

  LirParallelCopyExpanderTest() = default;
  ~LirParallelCopyExpanderTest() = default;

  static Value int32_type() {
    return Value(Value::Type::Integer, ValueSize::Size32);
  }

  static Value physical(int data) {
    return Value(Value::Type::Integer, ValueSize::Size32,
                 Value::Kind::PhysicalRegister, data);
  }

  static Value stack_slot(int data) {
    return Value(Value::Type::Integer, ValueSize::Size32,
                 Value::Kind::StackSlot, data);
  }

  void Expand(const std::vector<Task>& tasks, base::StringPiece expected);
  void ExpandWithScratch(const std::vector<Task>& tasks,
                         Value scratch,
                         base::StringPiece expected);
  void ExpandWithScratch2(const std::vector<Task>& tasks,
                          Value scratch1,
                          Value scratch2,
                          base::StringPiece expected);

 private:
  DISALLOW_COPY_AND_ASSIGN(LirParallelCopyExpanderTest);
};

void LirParallelCopyExpanderTest::Expand(const std::vector<Task>& tasks,
                                         base::StringPiece expected) {
  ExpandWithScratch2(tasks, Value(), Value(), expected);
}

void LirParallelCopyExpanderTest::ExpandWithScratch(
    const std::vector<Task>& tasks,
    Value scratch1,
    base::StringPiece expected) {
  ExpandWithScratch2(tasks, scratch1, Value(), expected);
}

void LirParallelCopyExpanderTest::ExpandWithScratch2(
    const std::vector<Task>& original_tasks,
    Value scratch1,
    Value scratch2,
    base::StringPiece expected) {
  DCHECK(!original_tasks.empty());
  std::vector<int> indexes(original_tasks.size());
  for (auto index = 0u; index < indexes.size(); ++index)
    indexes[index] = index;
  do {
    ParallelCopyExpander expander(factory(), int32_type());
    std::vector<Task> tasks(indexes.size());
    tasks.resize(0);
    for (auto const index : indexes)
      tasks.push_back(original_tasks[index]);
    for (auto task : tasks)
      expander.AddTask(task.first, task.second);
    if (scratch1.is_physical())
      expander.AddScratch(scratch1);
    if (scratch2.is_physical())
      expander.AddScratch(scratch2);

    std::stringstream ostream;
    for (auto const instr : expander.Expand())
      ostream << PrintAsGeneric(instr) << std::endl;
    EXPECT_EQ(expected, ostream.str());

    std::rotate(tasks.begin(), tasks.begin() + 1, tasks.end());
  } while (std::next_permutation(indexes.begin(), indexes.end()));
}

// Test cases...

TEST_F(LirParallelCopyExpanderTest, AutoScratchByImmediate) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(2)),
       std::make_pair(stack_slot(1), physical(0)),
       std::make_pair(physical(1), Value::SmallInt32(42)),
      },
      "mov sp[1] = R0\n"
      "mov R1 = sp[2]\n"
      "mov sp[0] = R1\n"
      "mov R1 = #42\n");
}

TEST_F(LirParallelCopyExpanderTest, AutoScratchByMemory) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(2)),
       std::make_pair(stack_slot(1), physical(0)),
       std::make_pair(physical(1), stack_slot(2)),
      },
      "mov sp[1] = R0\n"
      "mov R1 = sp[2]\n"
      "mov sp[0] = R1\n");
}

TEST_F(LirParallelCopyExpanderTest, AutoScratchByMemory2) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(2)),
       std::make_pair(stack_slot(1), physical(0)),
       std::make_pair(physical(1), stack_slot(3)),
      },
      "mov sp[1] = R0\n"
      "mov R1 = sp[2]\n"
      "mov sp[0] = R1\n"
      "mov R1 = sp[3]\n");
}

TEST_F(LirParallelCopyExpanderTest, Basic) {
  Expand(
      {
       std::make_pair(physical(0), physical(1)),
       std::make_pair(physical(2), physical(1)),
       std::make_pair(physical(4), physical(3)),
      },
      "mov R0 = R1\n"
      "mov R2 = R1\n"
      "mov R4 = R3\n");
}

TEST_F(LirParallelCopyExpanderTest, MemorySwap) {
  ExpandWithScratch2(
      {
       std::make_pair(stack_slot(0), stack_slot(1)),
       std::make_pair(stack_slot(1), stack_slot(0)),
      },
      physical(2), physical(3),
      "mov R3 = sp[1]\n"
      "mov R2 = sp[0]\n"
      "mov sp[0] = R3\n"
      "mov sp[1] = R2\n");
}

// memory swap requires 2 scratch register
TEST_F(LirParallelCopyExpanderTest, MemorySwapNoScratch) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(1)),
       std::make_pair(stack_slot(1), stack_slot(0)),
      },
      "");
}

// memory swap requires 2 scratch register
TEST_F(LirParallelCopyExpanderTest, MemorySwapOneScratch) {
  Expand(
      {
       std::make_pair(stack_slot(0), stack_slot(1)),
       std::make_pair(stack_slot(1), stack_slot(0)),
      },
      "");
}

TEST_F(LirParallelCopyExpanderTest, PhysicalToMemory) {
  Expand(
      {
       std::make_pair(stack_slot(0), physical(0)),
       std::make_pair(stack_slot(1), physical(1)),
      },
      "mov sp[0] = R0\n"
      "mov sp[1] = R1\n");
}

TEST_F(LirParallelCopyExpanderTest, Rotate) {
  Expand(
      {
       std::make_pair(physical(0), physical(1)),
       std::make_pair(physical(1), physical(2)),
       std::make_pair(physical(2), physical(0)),
      },
      "pcopy R0, R1 = R1, R0\n"
      "pcopy R1, R2 = R2, R1\n");
}

TEST_F(LirParallelCopyExpanderTest, RotateMemory) {
  ExpandWithScratch2(
      {
       std::make_pair(stack_slot(0), stack_slot(1)),
       std::make_pair(stack_slot(1), stack_slot(2)),
       std::make_pair(stack_slot(2), stack_slot(0)),
      },
      physical(4), physical(5),
      "mov R5 = sp[1]\n"
      "mov R4 = sp[0]\n"
      "mov sp[0] = R5\n"
      "mov R5 = sp[2]\n"
      "mov sp[1] = R5\n"
      "mov sp[2] = R4\n");
}

TEST_F(LirParallelCopyExpanderTest, RotateMemoryAndPhysical) {
  ExpandWithScratch(
      {
       std::make_pair(physical(0), physical(1)),
       std::make_pair(physical(1), stack_slot(2)),
       std::make_pair(stack_slot(2), physical(0)),
      },
      physical(2),
      "mov R2 = sp[2]\n"
      "mov sp[2] = R0\n"
      "mov R0 = R1\n"
      "mov R1 = R2\n");
}

TEST_F(LirParallelCopyExpanderTest, Swap) {
  Expand(
      {
       std::make_pair(physical(0), physical(1)),
       std::make_pair(physical(1), physical(0)),
      },
      "pcopy R0, R1 = R1, R0\n");
}

}  // namespace
}  // namespace lir
}  // namespace elang
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */
//------------------------------------------------------------------------------
//
// Run a json script layout file
//
//  - watches an named file and reloads actor tree if the file changes
//    ie run
//       builder-run layout.json
//
//       and edit layout.json in a text editor saving to trigger the reload
//
//------------------------------------------------------------------------------

#include <dali/dali.h>
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/public-api/builder/builder.h>
#include <dali-toolkit/public-api/builder/tree-node.h>
#include <map>
#include <string>
#include <fstream>
#include <streambuf>
#include <boost/scoped_ptr.hpp>

//#include <boost/regex.hpp>
#include "sys/stat.h"
#include <ctime>

#include <dali/integration-api/debug.h>

#define TOKEN_STRING(x) #x

using namespace Dali;
using namespace Dali::Toolkit;

namespace
{

std::string JSON_BROKEN("                                      \
{                                                              \
  'stage':                                                     \
  [                                                            \
    {                                                          \
      'type':'TextActor',                                      \
      'size': [50,50,1],                                       \
      'parent-origin': 'CENTER',                               \
      'text':'COULD NOT LOAD JSON FILE'                        \
    }                                                          \
  ]                                                            \
}                                                              \
");

std::string ReplaceQuotes(const std::string &single_quoted)
{
  std::string s(single_quoted);

  // wrong as no embedded quote but had regex link problems
  std::replace(s.begin(), s.end(), '\'', '"');

  return s;
}

} // anon namespace

//------------------------------------------------------------------------------
//
//
//
//------------------------------------------------------------------------------
class FileWatcher
{
public:
  FileWatcher(void);
  ~FileWatcher(void);
  explicit FileWatcher(const std::string &fn) { SetFilename(fn) ; };

  void SetFilename(const std::string &fn);
  std::string GetFilename();

  bool FileHasChanged(void);
  std::string GetFileContents(void) { return GetFileContents(mstringPath) ; };

private:
  // compiler does
  // FileWatcher(const FileWatcher&);
  // FileWatcher &operator=(const FileWatcher &);

  std::time_t mLastTime;
  std::string mstringPath;

  std::string GetFileContents(const std::string &fn)
  {
    std::ifstream t(fn.c_str());
    return std::string((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
  };
};

FileWatcher::FileWatcher(void) : mLastTime(0)
{
}

bool FileWatcher::FileHasChanged(void)
{
  struct stat buf;

  if(0 != stat(mstringPath.c_str(), &buf))
  {
    DALI_LOG_WARNING("File does not exist '%s'\n", mstringPath.c_str());
    return false;
  }
  else
  {
    if(buf.st_mtime > mLastTime)
    {
      mLastTime = buf.st_mtime;
      return true;
    }
    else
    {
      mLastTime = buf.st_mtime;
      return false;
    }
  }

  return false;
}

FileWatcher::~FileWatcher()
{
}

void FileWatcher::SetFilename(const std::string &fn)
{
  mstringPath = fn;
}

std::string FileWatcher::GetFilename(void)
{
  return mstringPath;
}

//------------------------------------------------------------------------------
//
//
//
//------------------------------------------------------------------------------
class ExampleApp : public ConnectionTracker
{
public:
  ExampleApp(Application &app) : mApp(app)
  {
    app.InitSignal().Connect(this, &ExampleApp::Create);

  }

  ~ExampleApp() {}

public:
  void SetJSONFilename(std::string const &fn) { fw.SetFilename(fn) ; };

  void Create(Application& app)
  {
    mTimer = Timer::New( 500 ); // ms
    mTimer.TickSignal().Connect( this, &ExampleApp::OnTimer);
    mTimer.Start();

    // Connect to key events in order to exit
    Stage::GetCurrent().KeyEventSignal().Connect(this, &ExampleApp::OnKeyEvent);
  }

private:
  Application& mApp;
  Layer mRootLayer;

  FileWatcher fw;
  Timer mTimer;

  void ReloadJsonFile(Builder& builder, Layer& layer)
  {
    Stage stage = Stage::GetCurrent();

    builder = Builder::New();

    PropertyValueMap defaultDirs;
    defaultDirs[ TOKEN_STRING(DALI_IMAGE_DIR) ]  = DALI_IMAGE_DIR;
    defaultDirs[ TOKEN_STRING(DALI_MODEL_DIR) ]  = DALI_MODEL_DIR;
    defaultDirs[ TOKEN_STRING(DALI_SCRIPT_DIR) ] = DALI_SCRIPT_DIR;

    builder.AddConstants( defaultDirs );

    if(!layer)
    {
      layer = Layer::New();
      layer.SetParentOrigin(ParentOrigin::CENTER);
      layer.SetAnchorPoint(AnchorPoint::CENTER);
      layer.SetSize( stage.GetRootLayer().GetCurrentSize() );
      stage.GetRootLayer().Add(layer);

      // render tasks may have been setup last load so remove them
      RenderTaskList taskList = stage.GetRenderTaskList();
      if( taskList.GetTaskCount() > 1 )
      {
        typedef std::vector<RenderTask> Collection;
        typedef Collection::iterator ColIter;
        Collection tasks;

        for(unsigned int i = 1; i < taskList.GetTaskCount(); ++i)
        {
          tasks.push_back( taskList.GetTask(i) );
        }

        for(ColIter iter = tasks.begin(); iter != tasks.end(); ++iter)
        {
          taskList.RemoveTask(*iter);
        }

        RenderTask defaultTask = taskList.GetTask(0);
        defaultTask.SetSourceActor( stage.GetRootLayer() );
        defaultTask.SetTargetFrameBuffer( FrameBufferImage() );
      }
    }

    unsigned int numChildren = layer.GetChildCount();

    for(unsigned int i=0; i<numChildren; ++i)
    {
      layer.Remove( layer.GetChildAt(0) );
    }

    std::string data(fw.GetFileContents());

    try
    {
      builder.LoadFromString(data);
    }
    catch(...)
    {
      builder.LoadFromString(ReplaceQuotes(JSON_BROKEN));
    }

    builder.AddActors( layer );

  }

  bool OnTimer(void)
  {
    if(fw.FileHasChanged())
    {
      ReloadJsonFile( mBuilder, mRootLayer );
    }

    return true;
  }

  // Process Key events to Quit on back-key
  void OnKeyEvent( const KeyEvent& event )
  {
    if( event.state == KeyEvent::Down )
    {
      if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
      {
        Application::Get().Quit();
      }
    }
  }

  Builder mBuilder;
};

//------------------------------------------------------------------------------
//
//
//
//------------------------------------------------------------------------------
int main(int argc, char **argv)
{
  Application dali_app = Application::New(&argc, &argv);

  ExampleApp app(dali_app);

  if(argc > 1)
  {
    std::cout << "Loading file:" << argc << " " << argv[1] << std::endl;
    app.SetJSONFilename(argv[1]);
  }
  else
  {
    DALI_ASSERT_ALWAYS(!"Specify JSON file on command line\n");
  }

  dali_app.MainLoop();

  return 0;
}
<commit_msg>(Builder) Stop using Application::Get()<commit_after>/*
 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */
//------------------------------------------------------------------------------
//
// Run a json script layout file
//
//  - watches an named file and reloads actor tree if the file changes
//    ie run
//       builder-run layout.json
//
//       and edit layout.json in a text editor saving to trigger the reload
//
//------------------------------------------------------------------------------

#include <dali/dali.h>
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/public-api/builder/builder.h>
#include <dali-toolkit/public-api/builder/tree-node.h>
#include <map>
#include <string>
#include <fstream>
#include <streambuf>
#include <boost/scoped_ptr.hpp>

//#include <boost/regex.hpp>
#include "sys/stat.h"
#include <ctime>

#include <dali/integration-api/debug.h>

#define TOKEN_STRING(x) #x

using namespace Dali;
using namespace Dali::Toolkit;

namespace
{

std::string JSON_BROKEN("                                      \
{                                                              \
  'stage':                                                     \
  [                                                            \
    {                                                          \
      'type':'TextActor',                                      \
      'size': [50,50,1],                                       \
      'parent-origin': 'CENTER',                               \
      'text':'COULD NOT LOAD JSON FILE'                        \
    }                                                          \
  ]                                                            \
}                                                              \
");

std::string ReplaceQuotes(const std::string &single_quoted)
{
  std::string s(single_quoted);

  // wrong as no embedded quote but had regex link problems
  std::replace(s.begin(), s.end(), '\'', '"');

  return s;
}

} // anon namespace

//------------------------------------------------------------------------------
//
//
//
//------------------------------------------------------------------------------
class FileWatcher
{
public:
  FileWatcher(void);
  ~FileWatcher(void);
  explicit FileWatcher(const std::string &fn) { SetFilename(fn) ; };

  void SetFilename(const std::string &fn);
  std::string GetFilename();

  bool FileHasChanged(void);
  std::string GetFileContents(void) { return GetFileContents(mstringPath) ; };

private:
  // compiler does
  // FileWatcher(const FileWatcher&);
  // FileWatcher &operator=(const FileWatcher &);

  std::time_t mLastTime;
  std::string mstringPath;

  std::string GetFileContents(const std::string &fn)
  {
    std::ifstream t(fn.c_str());
    return std::string((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
  };
};

FileWatcher::FileWatcher(void) : mLastTime(0)
{
}

bool FileWatcher::FileHasChanged(void)
{
  struct stat buf;

  if(0 != stat(mstringPath.c_str(), &buf))
  {
    DALI_LOG_WARNING("File does not exist '%s'\n", mstringPath.c_str());
    return false;
  }
  else
  {
    if(buf.st_mtime > mLastTime)
    {
      mLastTime = buf.st_mtime;
      return true;
    }
    else
    {
      mLastTime = buf.st_mtime;
      return false;
    }
  }

  return false;
}

FileWatcher::~FileWatcher()
{
}

void FileWatcher::SetFilename(const std::string &fn)
{
  mstringPath = fn;
}

std::string FileWatcher::GetFilename(void)
{
  return mstringPath;
}

//------------------------------------------------------------------------------
//
//
//
//------------------------------------------------------------------------------
class ExampleApp : public ConnectionTracker
{
public:
  ExampleApp(Application &app) : mApp(app)
  {
    app.InitSignal().Connect(this, &ExampleApp::Create);

  }

  ~ExampleApp() {}

public:
  void SetJSONFilename(std::string const &fn) { fw.SetFilename(fn) ; };

  void Create(Application& app)
  {
    mTimer = Timer::New( 500 ); // ms
    mTimer.TickSignal().Connect( this, &ExampleApp::OnTimer);
    mTimer.Start();

    // Connect to key events in order to exit
    Stage::GetCurrent().KeyEventSignal().Connect(this, &ExampleApp::OnKeyEvent);
  }

private:
  Application& mApp;
  Layer mRootLayer;

  FileWatcher fw;
  Timer mTimer;

  void ReloadJsonFile(Builder& builder, Layer& layer)
  {
    Stage stage = Stage::GetCurrent();

    builder = Builder::New();

    PropertyValueMap defaultDirs;
    defaultDirs[ TOKEN_STRING(DALI_IMAGE_DIR) ]  = DALI_IMAGE_DIR;
    defaultDirs[ TOKEN_STRING(DALI_MODEL_DIR) ]  = DALI_MODEL_DIR;
    defaultDirs[ TOKEN_STRING(DALI_SCRIPT_DIR) ] = DALI_SCRIPT_DIR;

    builder.AddConstants( defaultDirs );

    if(!layer)
    {
      layer = Layer::New();
      layer.SetParentOrigin(ParentOrigin::CENTER);
      layer.SetAnchorPoint(AnchorPoint::CENTER);
      layer.SetSize( stage.GetRootLayer().GetCurrentSize() );
      stage.GetRootLayer().Add(layer);

      // render tasks may have been setup last load so remove them
      RenderTaskList taskList = stage.GetRenderTaskList();
      if( taskList.GetTaskCount() > 1 )
      {
        typedef std::vector<RenderTask> Collection;
        typedef Collection::iterator ColIter;
        Collection tasks;

        for(unsigned int i = 1; i < taskList.GetTaskCount(); ++i)
        {
          tasks.push_back( taskList.GetTask(i) );
        }

        for(ColIter iter = tasks.begin(); iter != tasks.end(); ++iter)
        {
          taskList.RemoveTask(*iter);
        }

        RenderTask defaultTask = taskList.GetTask(0);
        defaultTask.SetSourceActor( stage.GetRootLayer() );
        defaultTask.SetTargetFrameBuffer( FrameBufferImage() );
      }
    }

    unsigned int numChildren = layer.GetChildCount();

    for(unsigned int i=0; i<numChildren; ++i)
    {
      layer.Remove( layer.GetChildAt(0) );
    }

    std::string data(fw.GetFileContents());

    try
    {
      builder.LoadFromString(data);
    }
    catch(...)
    {
      builder.LoadFromString(ReplaceQuotes(JSON_BROKEN));
    }

    builder.AddActors( layer );

  }

  bool OnTimer(void)
  {
    if(fw.FileHasChanged())
    {
      ReloadJsonFile( mBuilder, mRootLayer );
    }

    return true;
  }

  // Process Key events to Quit on back-key
  void OnKeyEvent( const KeyEvent& event )
  {
    if( event.state == KeyEvent::Down )
    {
      if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
      {
        mApp.Quit();
      }
    }
  }

  Builder mBuilder;
};

//------------------------------------------------------------------------------
//
//
//
//------------------------------------------------------------------------------
int main(int argc, char **argv)
{
  Application dali_app = Application::New(&argc, &argv);

  ExampleApp app(dali_app);

  if(argc > 1)
  {
    std::cout << "Loading file:" << argc << " " << argv[1] << std::endl;
    app.SetJSONFilename(argv[1]);
  }
  else
  {
    DALI_ASSERT_ALWAYS(!"Specify JSON file on command line\n");
  }

  dali_app.MainLoop();

  return 0;
}
<|endoftext|>


<commit_before>
/*
 * CodeQuery
 * Copyright (C) 2013 ruben2020 https://github.com/ruben2020/
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 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 <stdio.h>
#include <stdlib.h>
#include <memory>
#include "small_lib.h"
#include "optlist.h"
#include "sqlquery.h"
#include "swver.h"

void printhelp(const char* str)
{
	printf("Usage: %s [-s <sqdbfile> [-p n] [-t x] -[e|f] ] [-d] [-v] [-h]\n\n", str);
	printf("options:\n");
	printf("  -s   : CodeQuery sqlite3 db file path\n");
	printf("  -p n : parameter is a number denoted by n\n");
	printf("         default n = 1 (Symbol)\n");
	printf("  -t x : search term without spaces\n");
	printf("         if Exact Match is switched off, wild card\n");
	printf("         searches are possible. Use * and ?\n");
	printf("  -e   : Exact Match switched ON \n");
	printf("         Case-sensitive\n");
	printf("  -f   : Exact Match switched OFF (fuzzy search)\n");
	printf("         Case-insensitive with wild card search\n");
	printf("  -d   : debug\n");
	printf("  -v   : version\n");
	printf("  -h   : help\n\n");
	printf("The combinations possible are -s -t -e, -s -t -f\n");
	printf("The additional optional arguments are -d\n\n");
	printf("The possible values for n are:\n");
	printf("    1: Symbol (default)\n");
	printf("    2: Function or macro\n");
	printf("    3: Class or struct\n");
	printf("    4: Files including this file\n");
	printf("    5: Full file path\n");
	printf("    6: Functions calling this function\n");
	printf("    7: Functions called by this function\n");
	printf("    8: Members and methods of this class\n");
	printf("    9: Class which owns this member or method\n");
	printf("   10: Children of this class (inheritance)\n");
	printf("   11: Parent of this class (inheritance)\n\n");
	printf("Example:\n%s -s myproject.db -p 5 -t read*file -f\n\n", str);

}

void printlicense(void)
{
	printf(CODEQUERY_SW_VERSION);
	printf("\n");
	printf(CODEQUERY_SW_LICENSE);
}

bool fileexists(const char* fn)
{
	bool retval;
	FILE *fp;
	fp = fopen(fn, "r");
	retval = (fp != NULL);
	if (retval) fclose(fp);
	return retval;
}

void process_argwithopt(option_t* thisOpt, bool& err, tStr& fnstr, bool filemustexist)
{
	if (thisOpt->argument != NULL)
	{
		fnstr = thisOpt->argument;
		if (filemustexist && (fileexists(fnstr.c_str()) == false))
		{
			printf("Error: File %s doesn't exist.\n", fnstr.c_str());
			err = true;
		}
	}
	else
	{
		printf("Error: -%c used without file option.\n", thisOpt->option);
		err = true;
	}
}

int process_query(tStr sqfn, tStr term, tStr param, bool exact, bool debug)
{
	if ((sqfn.empty())||(term.empty())||(param.empty())) return 1;
	int retVal = 0;
	std::auto_ptr<sqlquery> sq(new sqlquery);
	sqlquery::en_filereadstatus filestatus = sq->open_dbfile(sqfn);
	switch (filestatus)
	{
		case sqlquery::sqlfileOK:
			break;
		case sqlquery::sqlfileOPENERROR:
			printf("Error: File %s open error!\n", sqfn.c_str());
			return 1;
		case sqlquery::sqlfileNOTCORRECTDB:
			printf("Error: File %s does not have correct database format!\n", sqfn.c_str());
			return 1;
		case sqlquery::sqlfileINCORRECTVER:
			printf("Error: File %s has an unsupported database version number!\n", sqfn.c_str());
			return 1;
		case sqlquery::sqlfileUNKNOWNERROR:
			printf("Error: Unknown Error!\n");
			return 1;
	}
	int intParam = atoi(param.c_str()) - 1;
	if ((intParam < 0) || (intParam > 10))
	{
		printf("Error: Parameter is out of range!\n");
		return 1;
	}
	sqlqueryresultlist resultlst;
	resultlst = sq->search(term, (sqlquery::en_queryType) intParam, exact);
	if (resultlst.result_type == sqlqueryresultlist::sqlresultERROR)
	{
		printf("Error: SQL Error! %s!\n", resultlst.sqlerrmsg.c_str());
		return 1;
	}
	for(std::vector<sqlqueryresult>::iterator it = resultlst.resultlist.begin();
		it != resultlst.resultlist.end(); it++)
	{
		switch(resultlst.result_type)
		{
			case sqlqueryresultlist::sqlresultFULL:
				printf("%s\t%s:%s\t%s\n", it->symname.c_str(),
				it->filename.c_str(), it->linenum.c_str(), it->linetext.c_str());
				break;
			case sqlqueryresultlist::sqlresultFILE_LINE:
				printf("%s:%s\t%s\n", it->filename.c_str(), it->linenum.c_str(),
				 it->linetext.c_str());
				break;
			case sqlqueryresultlist::sqlresultFILE_ONLY:
				printf("%s\n", it->filepath.c_str());
				break;
		}
	}
	return retVal;
}

int main(int argc, char *argv[])
{
    option_t *optList=NULL, *thisOpt=NULL;
    bool bSqlite, bParam, bTerm, bExact, bDebug, bVersion, bHelp, bError;
    int countExact = 0;
	bSqlite = false;
	bParam = false;
	bTerm = false;
	bExact = false;
	bDebug = false;
	bVersion = false;
	bHelp = (argc <= 1);
	bError = false;
	tStr sqfn, param = "1", term;

    /* get list of command line options and their arguments */
    optList = GetOptList(argc, argv, (char*)"s:p:t:efdvh");

    /* display results of parsing */
    while (optList != NULL)
    {
        thisOpt = optList;
        optList = optList->next;

		switch(thisOpt->option)
		{
			case 'v':
				bVersion = true;
				break;
			case 'h':
				bHelp = true;
				break;
			case 'e':
				bExact = true;
				countExact++;
				bError = bError || (countExact > 1);
				break;
			case 'f':
				bExact = false;
				countExact++;
				bError = bError || (countExact > 1);
				break;
			case 's':
				bSqlite = true;
				process_argwithopt(thisOpt, bError, sqfn, true);
				break;
			case 'p':
				bParam = true;
				param = thisOpt->argument;
				break;
			case 't':
				bTerm = true;
				term = thisOpt->argument;
				break;
			case 'd':
				bDebug = true;
				break;
			default:
				break;
		}
        free(thisOpt);    /* done with this item, free it */
    }
	if (bVersion)
	{
		printlicense();
		return 0;
	}
	if (bHelp || bError)
	{
		printhelp(extract_filename(argv[0]));
		return (bError ? 1 : 0);
	}
	if (!bSqlite)
	{
		printf("Error: -s is required.\n");
		bError = true;
	}
	if (!bTerm)
	{
		printf("Error: -t is required.\n");
		bError = true;
	}
	if (bError)
	{
		printhelp(extract_filename(argv[0]));
		return 1;
	}
	if (bSqlite && bTerm)
	{
		bError = process_query(sqfn, term, param, bExact, bDebug);
	}
	if (bError)
	{
		printhelp(extract_filename(argv[0]));
	}
	return bError;
}

<commit_msg>updated CLI<commit_after>
/*
 * CodeQuery
 * Copyright (C) 2013 ruben2020 https://github.com/ruben2020/
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 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 <stdio.h>
#include <stdlib.h>
#include <memory>
#include "small_lib.h"
#include "optlist.h"
#include "sqlquery.h"
#include "swver.h"

void printhelp(const char* str)
{
	printf("Usage: %s [-s <sqdbfile> [-p <n>] [-t <term>] -[e|f] ] [-d] [-v] [-h]\n\n", str);
	printf("options:\n");
	printf("  -s : CodeQuery sqlite3 db file path\n");
	printf("  -p : parameter is a number denoted by n\n");
	printf("       default n = 1 (Symbol)\n");
	printf("  -t : search term without spaces\n");
	printf("       if Exact Match is switched off, wild card\n");
	printf("       searches are possible. Use * and ?\n");
	printf("  -e : Exact Match switched ON \n");
	printf("       Case-sensitive\n");
	printf("  -f : Exact Match switched OFF (fuzzy search)\n");
	printf("       Case-insensitive with wild card search\n");
	printf("  -d : debug\n");
	printf("  -v : version\n");
	printf("  -h : help\n\n");
	printf("The combinations possible are -s -t -e, -s -t -f\n");
	printf("The additional optional arguments are -d\n\n");
	printf("The possible values for n are:\n");
	printf("    1: Symbol (default)\n");
	printf("    2: Function or macro\n");
	printf("    3: Class or struct\n");
	printf("    4: Files including this file\n");
	printf("    5: Full file path\n");
	printf("    6: Functions calling this function\n");
	printf("    7: Functions called by this function\n");
	printf("    8: Members and methods of this class\n");
	printf("    9: Class which owns this member or method\n");
	printf("   10: Children of this class (inheritance)\n");
	printf("   11: Parent of this class (inheritance)\n\n");
	printf("Example:\n%s -s myproject.db -p 6 -t read*file -f\n\n", str);

}

void printlicense(void)
{
	printf(CODEQUERY_SW_VERSION);
	printf("\n");
	printf(CODEQUERY_SW_LICENSE);
}

bool fileexists(const char* fn)
{
	bool retval;
	FILE *fp;
	fp = fopen(fn, "r");
	retval = (fp != NULL);
	if (retval) fclose(fp);
	return retval;
}

void process_argwithopt(option_t* thisOpt, bool& err, tStr& fnstr, bool filemustexist)
{
	if (thisOpt->argument != NULL)
	{
		fnstr = thisOpt->argument;
		if (filemustexist && (fileexists(fnstr.c_str()) == false))
		{
			printf("Error: File %s doesn't exist.\n", fnstr.c_str());
			err = true;
		}
	}
	else
	{
		printf("Error: -%c used without file option.\n", thisOpt->option);
		err = true;
	}
}

int process_query(tStr sqfn, tStr term, tStr param, bool exact, bool debug)
{
	if ((sqfn.empty())||(term.empty())||(param.empty())) return 1;
	int retVal = 0;
	std::auto_ptr<sqlquery> sq(new sqlquery);
	sqlquery::en_filereadstatus filestatus = sq->open_dbfile(sqfn);
	switch (filestatus)
	{
		case sqlquery::sqlfileOK:
			break;
		case sqlquery::sqlfileOPENERROR:
			printf("Error: File %s open error!\n", sqfn.c_str());
			return 1;
		case sqlquery::sqlfileNOTCORRECTDB:
			printf("Error: File %s does not have correct database format!\n", sqfn.c_str());
			return 1;
		case sqlquery::sqlfileINCORRECTVER:
			printf("Error: File %s has an unsupported database version number!\n", sqfn.c_str());
			return 1;
		case sqlquery::sqlfileUNKNOWNERROR:
			printf("Error: Unknown Error!\n");
			return 1;
	}
	int intParam = atoi(param.c_str()) - 1;
	if ((intParam < 0) || (intParam > 10))
	{
		printf("Error: Parameter is out of range!\n");
		return 1;
	}
	sqlqueryresultlist resultlst;
	resultlst = sq->search(term, (sqlquery::en_queryType) intParam, exact);
	if (resultlst.result_type == sqlqueryresultlist::sqlresultERROR)
	{
		printf("Error: SQL Error! %s!\n", resultlst.sqlerrmsg.c_str());
		return 1;
	}
	for(std::vector<sqlqueryresult>::iterator it = resultlst.resultlist.begin();
		it != resultlst.resultlist.end(); it++)
	{
		switch(resultlst.result_type)
		{
			case sqlqueryresultlist::sqlresultFULL:
				printf("%s\t%s:%s\t%s\n", it->symname.c_str(),
				it->filename.c_str(), it->linenum.c_str(), it->linetext.c_str());
				break;
			case sqlqueryresultlist::sqlresultFILE_LINE:
				printf("%s:%s\t%s\n", it->filename.c_str(), it->linenum.c_str(),
				 it->linetext.c_str());
				break;
			case sqlqueryresultlist::sqlresultFILE_ONLY:
				printf("%s\n", it->filepath.c_str());
				break;
		}
	}
	return retVal;
}

int main(int argc, char *argv[])
{
    option_t *optList=NULL, *thisOpt=NULL;
    bool bSqlite, bParam, bTerm, bExact, bDebug, bVersion, bHelp, bError;
    int countExact = 0;
	bSqlite = false;
	bParam = false;
	bTerm = false;
	bExact = false;
	bDebug = false;
	bVersion = false;
	bHelp = (argc <= 1);
	bError = false;
	tStr sqfn, param = "1", term;

    /* get list of command line options and their arguments */
    optList = GetOptList(argc, argv, (char*)"s:p:t:efdvh");

    /* display results of parsing */
    while (optList != NULL)
    {
        thisOpt = optList;
        optList = optList->next;

		switch(thisOpt->option)
		{
			case 'v':
				bVersion = true;
				break;
			case 'h':
				bHelp = true;
				break;
			case 'e':
				bExact = true;
				countExact++;
				bError = bError || (countExact > 1);
				if (countExact > 1) printf("Error: either -e or -f but not both!\n");
				break;
			case 'f':
				bExact = false;
				countExact++;
				bError = bError || (countExact > 1);
				if (countExact > 1) printf("Error: either -e or -f but not both!\n");
				break;
			case 's':
				bSqlite = true;
				process_argwithopt(thisOpt, bError, sqfn, true);
				break;
			case 'p':
				bParam = true;
				param = thisOpt->argument;
				break;
			case 't':
				bTerm = true;
				term = thisOpt->argument;
				break;
			case 'd':
				bDebug = true;
				break;
			default:
				break;
		}
        free(thisOpt);    /* done with this item, free it */
    }
	if (bVersion)
	{
		printlicense();
		return 0;
	}
	if (bHelp || bError)
	{
		printhelp(extract_filename(argv[0]));
		return (bError ? 1 : 0);
	}
	if (!bSqlite)
	{
		printf("Error: -s is required.\n");
		bError = true;
	}
	if (!bTerm)
	{
		printf("Error: -t is required.\n");
		bError = true;
	}
	if (bError)
	{
		printhelp(extract_filename(argv[0]));
		return 1;
	}
	if (bSqlite && bTerm)
	{
		bError = process_query(sqfn, term, param, bExact, bDebug);
	}
	if (bError)
	{
		printhelp(extract_filename(argv[0]));
	}
	return bError;
}

<|endoftext|>


<commit_before>
// Qt includes
#include <QtGlobal>
#include <QStringList>
#include <QRegExp>

// Visomics includes
#include "voUtils.h"

// VTK includes
#include <vtkDoubleArray.h>
#include <vtkIntArray.h>
#include <vtkNew.h>
#include <vtkSmartPointer.h>
#include <vtkStringArray.h>
#include <vtkTable.h>
#include <vtkVariantArray.h>

#include <QDebug>

namespace
{
//----------------------------------------------------------------------------
template<typename ArrayType, typename ValueType>
bool transposeColumn(vtkTable* srcTable, vtkTable* destTable, int columnId, bool useVariant = false)
{
  if (!srcTable || !destTable)
    {
    return false;
    }
  if (columnId < 0 || columnId >= srcTable->GetNumberOfColumns())
    {
    return false;
    }
  vtkAbstractArray * column = srcTable->GetColumn(columnId);
  ArrayType * typeColumn = ArrayType::SafeDownCast(column);
  if (!typeColumn && !useVariant)
    {
    return false;
    }

  for (int rid = 0; rid < column->GetNumberOfTuples() * column->GetNumberOfComponents(); ++rid)
    {
    vtkSmartPointer<ArrayType> transposedColumn;
    if (columnId == 0)
      {
      transposedColumn = vtkSmartPointer<ArrayType>::New();
      transposedColumn->SetNumberOfValues(srcTable->GetNumberOfColumns());
      destTable->AddColumn(transposedColumn);
      }
    else
      {
      transposedColumn = ArrayType::SafeDownCast(destTable->GetColumn(rid));
      }
    Q_ASSERT(transposedColumn);
    if (!useVariant)
      {
      ValueType value = typeColumn->GetValue(rid);
      transposedColumn->SetValue(columnId, value);
      }
    else
      {
      vtkVariant value = column->GetVariantValue(rid);
      transposedColumn->SetVariantValue(columnId, value);
      }
    }
  return true;
}
}

//----------------------------------------------------------------------------
bool voUtils::transposeTable(vtkTable* srcTable, vtkTable* destTable)
{
  if (!srcTable)
    {
    return false;
    }

  if (!destTable)
    {
    return false;
    }

  if (srcTable->GetNumberOfColumns() == 0)
    {
    return true;
    }

  bool useVariant = false;
  vtkAbstractArray * firstColumn = srcTable->GetColumn(0);
  for (int cid = 1; cid < srcTable->GetNumberOfColumns(); ++cid)
    {
    if (qstrcmp(firstColumn->GetClassName(), srcTable->GetColumn(cid)->GetClassName()) != 0)
      {
      useVariant = true;
      break;
      }
    }

  for(int cid = 0; cid < srcTable->GetNumberOfColumns(); ++cid)
    {
    if (!useVariant)
      {
      if (!transposeColumn<vtkDoubleArray, double>(srcTable, destTable, cid))
        {
        if (!transposeColumn<vtkIntArray, int>(srcTable, destTable, cid))
          {
          if (!transposeColumn<vtkStringArray, vtkStdString>(srcTable, destTable, cid))
            {
            if (!transposeColumn<vtkVariantArray, vtkVariant>(srcTable, destTable, cid))
              {
              return false;
              }
            }
          }
        }
      }
    else
      {
      if (!transposeColumn<vtkVariantArray, vtkVariant>(srcTable, destTable, cid, useVariant))
        {
        return false;
        }
      }
    }

  return true;
}

//----------------------------------------------------------------------------
bool voUtils::transposeTable(vtkTable* table)
{
  vtkNew<vtkTable> transposedTable;
  bool success = voUtils::transposeTable(table, transposedTable.GetPointer());
  if (!success)
    {
    return false;
    }
  table->ShallowCopy(transposedTable.GetPointer());
  return true;
}

//----------------------------------------------------------------------------
bool voUtils::insertColumnIntoTable(vtkTable * table, int position, vtkAbstractArray * columnToInsert)
{
  if (!table)
    {
    return false;
    }
  if (!columnToInsert)
    {
    return false;
    }
  if (table->GetNumberOfRows() != columnToInsert->GetNumberOfComponents() * columnToInsert->GetNumberOfTuples())
    {
    return false;
    }
  if (position < 0)
    {
    position = 0;
    }
  if (position > table->GetNumberOfColumns())
    {
    position = table->GetNumberOfColumns();
    }

  vtkNew<vtkTable> updatedTable;
  for (int cid = 0; cid < table->GetNumberOfColumns(); ++cid)
    {
    vtkAbstractArray * column = table->GetColumn(cid);
    Q_ASSERT(column);
    if (cid == position)
      {
      updatedTable->AddColumn(columnToInsert);
      }
    updatedTable->AddColumn(column);
    }
  if (position == table->GetNumberOfColumns())
    {
    updatedTable->AddColumn(columnToInsert);
    }
  table->ShallowCopy(updatedTable.GetPointer());
  return true;
}

//----------------------------------------------------------------------------
void voUtils::setTableColumnNames(vtkTable * table, vtkStringArray * columnNames)
{
  if (!table)
    {
    return;
    }
  if (!columnNames)
    {
    return;
    }

  for (int cid = 0; cid < table->GetNumberOfColumns() && cid < columnNames->GetNumberOfValues(); ++cid)
    {
    vtkAbstractArray * column = table->GetColumn(cid);
    Q_ASSERT(column);
    column->SetName(columnNames->GetValue(cid));
    }
}

//----------------------------------------------------------------------------
bool voUtils::parseRangeString(const QString& rangeString, QList<int>& rangeList, bool alpha)
{
  if(!rangeList.empty())
    {
    return false;
    }

  if(rangeString.isEmpty())
    {
    return true;
    }

  // Validate - checks for form, not semantics
  QRegExp validRegEx;
  if (!alpha) // Numbers
    {
    validRegEx.setPattern("^(\\d+[-,])*\\d+$");
    }
  else // Letters
    {
    validRegEx.setPattern("^([A-Z]+[-,])*[A-Z]+$");
    validRegEx.setCaseSensitivity(Qt::CaseInsensitive);
    }
  QString scratchString(rangeString);
  scratchString.replace(" ", "");
  if(!validRegEx.exactMatch(scratchString))
    {
    return false;
    }

  // Parse
  QStringList rangeStringList = scratchString.split(",");
  rangeStringList.removeDuplicates();

  QRegExp rangeRegEx;
  if (!alpha)
    {
    rangeRegEx.setPattern("^(\\d+)-(\\d+)$");
    }
  else
    {
    rangeRegEx.setPattern("^([A-Z]+)-([A-Z]+)$");
    rangeRegEx.setCaseSensitivity(Qt::CaseInsensitive);
    }
  foreach(const QString& subStr, rangeStringList)
    {
    if(rangeRegEx.indexIn(subStr) != -1)
      {
      int subBegin;
      int subEnd;
      if (!alpha)
        {
        subBegin = rangeRegEx.cap(1).toInt() - 1;
        subEnd = rangeRegEx.cap(2).toInt() - 1;
        }
      else
        {
        subBegin = voUtils::counterAlphaToInt(rangeRegEx.cap(1));
        subEnd = voUtils::counterAlphaToInt(rangeRegEx.cap(2));
        }
      for(int subCtr = subBegin; subCtr <= subEnd; subCtr++)
        {
        rangeList.push_back(subCtr);
        }
      }
    else
      {
      if (!alpha)
        {
        rangeList.push_back(subStr.toInt() - 1);
        }
      else
        {
        rangeList.push_back(voUtils::counterAlphaToInt(subStr));
        }
      }
    }

  rangeList = rangeList.toSet().toList(); // Remove duplicates
  qSort(rangeList);

  return true;
}

//----------------------------------------------------------------------------
QString voUtils::counterIntToAlpha(int intVal)
{
  if (intVal < 0)
    {
    return QString();
    }
  else if (intVal < 26)
    {
    return QString(QChar('A' + intVal));
    }
  else
    {
    return voUtils::counterIntToAlpha((intVal / 26) - 1) + voUtils::counterIntToAlpha(intVal % 26);
    }
}

//----------------------------------------------------------------------------
int voUtils::counterAlphaToInt(const QString& alphaVal)
{
  if (alphaVal.length() < 1)
    {
    return -1;
    }
  else if (alphaVal.length() == 1)
    {
    return static_cast<int>(alphaVal.toUpper().at(0).toLatin1() - 'A');
    }
  else
    {
    return (voUtils::counterAlphaToInt(alphaVal.mid(0, alphaVal.length()-1)) + 1) * 26
           + voUtils::counterAlphaToInt(alphaVal.mid(alphaVal.length()-1));
    }
}

<commit_msg>voUtils - Remove unused header<commit_after>
// Qt includes
#include <QtGlobal>
#include <QStringList>
#include <QRegExp>
#include <QSet>

// Visomics includes
#include "voUtils.h"

// VTK includes
#include <vtkDoubleArray.h>
#include <vtkIntArray.h>
#include <vtkNew.h>
#include <vtkSmartPointer.h>
#include <vtkStringArray.h>
#include <vtkTable.h>
#include <vtkVariantArray.h>

namespace
{
//----------------------------------------------------------------------------
template<typename ArrayType, typename ValueType>
bool transposeColumn(vtkTable* srcTable, vtkTable* destTable, int columnId, bool useVariant = false)
{
  if (!srcTable || !destTable)
    {
    return false;
    }
  if (columnId < 0 || columnId >= srcTable->GetNumberOfColumns())
    {
    return false;
    }
  vtkAbstractArray * column = srcTable->GetColumn(columnId);
  ArrayType * typeColumn = ArrayType::SafeDownCast(column);
  if (!typeColumn && !useVariant)
    {
    return false;
    }

  for (int rid = 0; rid < column->GetNumberOfTuples() * column->GetNumberOfComponents(); ++rid)
    {
    vtkSmartPointer<ArrayType> transposedColumn;
    if (columnId == 0)
      {
      transposedColumn = vtkSmartPointer<ArrayType>::New();
      transposedColumn->SetNumberOfValues(srcTable->GetNumberOfColumns());
      destTable->AddColumn(transposedColumn);
      }
    else
      {
      transposedColumn = ArrayType::SafeDownCast(destTable->GetColumn(rid));
      }
    Q_ASSERT(transposedColumn);
    if (!useVariant)
      {
      ValueType value = typeColumn->GetValue(rid);
      transposedColumn->SetValue(columnId, value);
      }
    else
      {
      vtkVariant value = column->GetVariantValue(rid);
      transposedColumn->SetVariantValue(columnId, value);
      }
    }
  return true;
}
}

//----------------------------------------------------------------------------
bool voUtils::transposeTable(vtkTable* srcTable, vtkTable* destTable)
{
  if (!srcTable)
    {
    return false;
    }

  if (!destTable)
    {
    return false;
    }

  if (srcTable->GetNumberOfColumns() == 0)
    {
    return true;
    }

  bool useVariant = false;
  vtkAbstractArray * firstColumn = srcTable->GetColumn(0);
  for (int cid = 1; cid < srcTable->GetNumberOfColumns(); ++cid)
    {
    if (qstrcmp(firstColumn->GetClassName(), srcTable->GetColumn(cid)->GetClassName()) != 0)
      {
      useVariant = true;
      break;
      }
    }

  for(int cid = 0; cid < srcTable->GetNumberOfColumns(); ++cid)
    {
    if (!useVariant)
      {
      if (!transposeColumn<vtkDoubleArray, double>(srcTable, destTable, cid))
        {
        if (!transposeColumn<vtkIntArray, int>(srcTable, destTable, cid))
          {
          if (!transposeColumn<vtkStringArray, vtkStdString>(srcTable, destTable, cid))
            {
            if (!transposeColumn<vtkVariantArray, vtkVariant>(srcTable, destTable, cid))
              {
              return false;
              }
            }
          }
        }
      }
    else
      {
      if (!transposeColumn<vtkVariantArray, vtkVariant>(srcTable, destTable, cid, useVariant))
        {
        return false;
        }
      }
    }

  return true;
}

//----------------------------------------------------------------------------
bool voUtils::transposeTable(vtkTable* table)
{
  vtkNew<vtkTable> transposedTable;
  bool success = voUtils::transposeTable(table, transposedTable.GetPointer());
  if (!success)
    {
    return false;
    }
  table->ShallowCopy(transposedTable.GetPointer());
  return true;
}

//----------------------------------------------------------------------------
bool voUtils::insertColumnIntoTable(vtkTable * table, int position, vtkAbstractArray * columnToInsert)
{
  if (!table)
    {
    return false;
    }
  if (!columnToInsert)
    {
    return false;
    }
  if (table->GetNumberOfRows() != columnToInsert->GetNumberOfComponents() * columnToInsert->GetNumberOfTuples())
    {
    return false;
    }
  if (position < 0)
    {
    position = 0;
    }
  if (position > table->GetNumberOfColumns())
    {
    position = table->GetNumberOfColumns();
    }

  vtkNew<vtkTable> updatedTable;
  for (int cid = 0; cid < table->GetNumberOfColumns(); ++cid)
    {
    vtkAbstractArray * column = table->GetColumn(cid);
    Q_ASSERT(column);
    if (cid == position)
      {
      updatedTable->AddColumn(columnToInsert);
      }
    updatedTable->AddColumn(column);
    }
  if (position == table->GetNumberOfColumns())
    {
    updatedTable->AddColumn(columnToInsert);
    }
  table->ShallowCopy(updatedTable.GetPointer());
  return true;
}

//----------------------------------------------------------------------------
void voUtils::setTableColumnNames(vtkTable * table, vtkStringArray * columnNames)
{
  if (!table)
    {
    return;
    }
  if (!columnNames)
    {
    return;
    }

  for (int cid = 0; cid < table->GetNumberOfColumns() && cid < columnNames->GetNumberOfValues(); ++cid)
    {
    vtkAbstractArray * column = table->GetColumn(cid);
    Q_ASSERT(column);
    column->SetName(columnNames->GetValue(cid));
    }
}

//----------------------------------------------------------------------------
bool voUtils::parseRangeString(const QString& rangeString, QList<int>& rangeList, bool alpha)
{
  if(!rangeList.empty())
    {
    return false;
    }

  if(rangeString.isEmpty())
    {
    return true;
    }

  // Validate - checks for form, not semantics
  QRegExp validRegEx;
  if (!alpha) // Numbers
    {
    validRegEx.setPattern("^(\\d+[-,])*\\d+$");
    }
  else // Letters
    {
    validRegEx.setPattern("^([A-Z]+[-,])*[A-Z]+$");
    validRegEx.setCaseSensitivity(Qt::CaseInsensitive);
    }
  QString scratchString(rangeString);
  scratchString.replace(" ", "");
  if(!validRegEx.exactMatch(scratchString))
    {
    return false;
    }

  // Parse
  QStringList rangeStringList = scratchString.split(",");
  rangeStringList.removeDuplicates();

  QRegExp rangeRegEx;
  if (!alpha)
    {
    rangeRegEx.setPattern("^(\\d+)-(\\d+)$");
    }
  else
    {
    rangeRegEx.setPattern("^([A-Z]+)-([A-Z]+)$");
    rangeRegEx.setCaseSensitivity(Qt::CaseInsensitive);
    }
  foreach(const QString& subStr, rangeStringList)
    {
    if(rangeRegEx.indexIn(subStr) != -1)
      {
      int subBegin;
      int subEnd;
      if (!alpha)
        {
        subBegin = rangeRegEx.cap(1).toInt() - 1;
        subEnd = rangeRegEx.cap(2).toInt() - 1;
        }
      else
        {
        subBegin = voUtils::counterAlphaToInt(rangeRegEx.cap(1));
        subEnd = voUtils::counterAlphaToInt(rangeRegEx.cap(2));
        }
      for(int subCtr = subBegin; subCtr <= subEnd; subCtr++)
        {
        rangeList.push_back(subCtr);
        }
      }
    else
      {
      if (!alpha)
        {
        rangeList.push_back(subStr.toInt() - 1);
        }
      else
        {
        rangeList.push_back(voUtils::counterAlphaToInt(subStr));
        }
      }
    }

  rangeList = rangeList.toSet().toList(); // Remove duplicates
  qSort(rangeList);

  return true;
}

//----------------------------------------------------------------------------
QString voUtils::counterIntToAlpha(int intVal)
{
  if (intVal < 0)
    {
    return QString();
    }
  else if (intVal < 26)
    {
    return QString(QChar('A' + intVal));
    }
  else
    {
    return voUtils::counterIntToAlpha((intVal / 26) - 1) + voUtils::counterIntToAlpha(intVal % 26);
    }
}

//----------------------------------------------------------------------------
int voUtils::counterAlphaToInt(const QString& alphaVal)
{
  if (alphaVal.length() < 1)
    {
    return -1;
    }
  else if (alphaVal.length() == 1)
    {
    return static_cast<int>(alphaVal.toUpper().at(0).toLatin1() - 'A');
    }
  else
    {
    return (voUtils::counterAlphaToInt(alphaVal.mid(0, alphaVal.length()-1)) + 1) * 26
           + voUtils::counterAlphaToInt(alphaVal.mid(alphaVal.length()-1));
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright 2016-2020 Christian Lockley
 *
 * 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 "watchdogd.hpp"
#include "linux.hpp"
#include "watchdog.hpp"
#include "logutils.hpp"

int Watchdog::Ping()
{
	int tmp = 0;

	if (ioctl(fd, WDIOC_KEEPALIVE, &tmp) == 0) {
		return 0;
	}

	ioctl(fd, WDIOC_SETTIMEOUT, &timeout);

	if (ioctl(fd, WDIOC_KEEPALIVE, &tmp) == 0) {
		return 0;
	}

	Logmsg(LOG_ERR, "WDIOC_KEEPALIVE ioctl failed: %s", MyStrerror(errno));

	return -1;
}

int Watchdog::Close()
{
	if (fd == -1) {
		return 0;
	}

	if (write(fd, "V", strlen("V")) < 0) {
		Logmsg(LOG_CRIT, "write to watchdog device failed: %s",
		       MyStrerror(errno));
		close(fd);
		Logmsg(LOG_CRIT, "unable to close watchdog device");
		return -1;
	} else {
		close(fd);
	}

	return 0;
}

bool Watchdog::CanMagicClose()
{
	struct watchdog_info watchDogInfo = {0};

	if (ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo) < 0) {
		Logmsg(LOG_ERR, "%s", MyStrerror(errno));
		return false;
	}
	if (strcmp((const char*)GetIdentity(),"iamt_wdt") == 0) {
		return true; //iamt_wdt is broken
	}
	return (WDIOF_MAGICCLOSE & watchDogInfo.options);
}

bool Watchdog::PrintWdtInfo()
{
	struct watchdog_info watchDogInfo;

	if (ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo) < 0) {
		Logmsg(LOG_ERR, "%s", MyStrerror(errno));
	} else {
		if (strcasecmp((const char*)watchDogInfo.identity, "software watchdog") != 0) {
			Logmsg(LOG_DEBUG, "Hardware watchdog '%s', version %u",
			       watchDogInfo.identity, watchDogInfo.firmware_version);
		} else {
			Logmsg(LOG_DEBUG, "%s, version %u",
			       watchDogInfo.identity, watchDogInfo.firmware_version);
		}
		dev dev;
		GetDeviceMajorMinor(&dev, (char*)path);
		Logmsg(LOG_DEBUG, "Device: %s Major: %li Minor: %li", path, dev.major, dev.minor);
		return true;
	}

	return false;
}

unsigned char * Watchdog::GetIdentity()
{
	static struct watchdog_info watchDogInfo;

	this->Ping();

	if (ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo) < 0) {
		Logmsg(LOG_ERR, "%s", MyStrerror(errno));
		return NULL;
	}

	return watchDogInfo.identity;
}

int Watchdog::Open(const char *const path)
{
	if (path == NULL) {
		return -1;
	}

	fd = open(path, O_WRONLY | O_CLOEXEC);

	if (fd == -1) {

		Logmsg(LOG_ERR,
		       "unable to open watchdog device: %s", MyStrerror(errno));
		return -1;
	}

	if (this->Ping() != 0) {
		Close();
		return -1;
	}

	if (CanMagicClose() == false) {
		Logmsg(LOG_ALERT,
		       "watchdog device does not support magic close char");
	}

	strcpy((char *)this->path, path);

	return 0;
}

int Watchdog::GetOptimalPingInterval()
{
	int timeout = 0;

	if (ioctl(fd, WDIOC_GETTIMEOUT, &timeout) < 0) {
		return 1;
	}

	timeout /= 2;

	if (timeout < 1)
		return 1;

	return timeout;
}

int Watchdog::Disable()
{
	int options = WDIOS_DISABLECARD;
	if (ioctl(fd, WDIOC_SETOPTIONS, &options) < 0) {
		Logmsg(LOG_CRIT, "WDIOS_DISABLECARD ioctl failed: %s",
		       MyStrerror(errno));
		return -1;
	}

	return 0;
}

int Watchdog::Enable()
{
	int options = WDIOS_ENABLECARD;
	if (ioctl(fd, WDIOC_SETOPTIONS, &options) < 0) {
		Logmsg(LOG_CRIT, "WDIOS_ENABLECARD ioctl failed: %s",
		       MyStrerror(errno));
		return -1;
	}

	return 0;
}

int Watchdog::ConfigureWatchdogTimeout(int timeout)
{
	struct watchdog_info watchDogInfo;

	if (timeout <= 0)
		return 0;

	if (Disable() < 0) {
		return -1;
	}

	if (ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo) < 0) {
		Logmsg(LOG_CRIT, "WDIOC_GETSUPPORT ioctl failed: %s",
		       MyStrerror(errno));
		return -1;
	}

	if (!(watchDogInfo.options & WDIOF_SETTIMEOUT)) {
		return -1;
	}

	int oldTimeout = timeout;

	if (ioctl(fd, WDIOC_SETTIMEOUT, &timeout) < 0) {
		this->timeout = GetOptimalPingInterval();

		fprintf(stderr, "watchdogd: unable to set WDT timeout\n");
		fprintf(stderr, "using default: %i", this->timeout);

		if (Enable() < 0) {
			return -1;
		}

		return Ping();
	}

	if (timeout != oldTimeout) {
		fprintf(stderr, "watchdogd: Actual WDT timeout: %i seconds\n",
			timeout);
		fprintf(stderr,
			"watchdogd: Timeout specified in the configuration file: %i\n",
			oldTimeout);
	}

	this->timeout = timeout;

	if (Enable() < 0) {
		return -1;
	}

	return Ping();
}

long unsigned Watchdog::GetStatus()
{
	long unsigned status = 0;

	ioctl(fd, WDIOC_GETBOOTSTATUS, &status);

	return status;
}

long Watchdog::GetFirmwareVersion()
{
	struct watchdog_info watchDogInfo = {0};

	ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo);

	return watchDogInfo.firmware_version;
}

long Watchdog::GetTimeleft()
{
	int timeleft = 0;

	if (ioctl(fd, WDIOC_GETTIMELEFT, &timeleft) < 0) {
		return -1;
	}

	return timeleft;
}

int Watchdog::GetRawTimeout()
{
	int timeout = 0;
	ioctl(fd, WDIOC_GETTIMEOUT, &timeout);
	return timeout;
}

bool Watchdog::CheckWatchdogTimeout(int timeout)
{
	if (timeout <= this->timeout) {
		return false;
	}
	return true;
}
<commit_msg>ensure timeout is not 0<commit_after>/*
 * Copyright 2016-2020 Christian Lockley
 *
 * 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 "watchdogd.hpp"
#include "linux.hpp"
#include "watchdog.hpp"
#include "logutils.hpp"

int Watchdog::Ping()
{
	int tmp = 0;

	if (ioctl(fd, WDIOC_KEEPALIVE, &tmp) == 0) {
		return 0;
	}

	ioctl(fd, WDIOC_SETTIMEOUT, &timeout);

	if (ioctl(fd, WDIOC_KEEPALIVE, &tmp) == 0) {
		return 0;
	}

	Logmsg(LOG_ERR, "WDIOC_KEEPALIVE ioctl failed: %s", MyStrerror(errno));

	return -1;
}

int Watchdog::Close()
{
	if (fd == -1) {
		return 0;
	}

	if (write(fd, "V", strlen("V")) < 0) {
		Logmsg(LOG_CRIT, "write to watchdog device failed: %s",
		       MyStrerror(errno));
		close(fd);
		Logmsg(LOG_CRIT, "unable to close watchdog device");
		return -1;
	} else {
		close(fd);
	}

	return 0;
}

bool Watchdog::CanMagicClose()
{
	struct watchdog_info watchDogInfo = {0};

	if (ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo) < 0) {
		Logmsg(LOG_ERR, "%s", MyStrerror(errno));
		return false;
	}
	if (strcmp((const char*)GetIdentity(),"iamt_wdt") == 0) {
		return true; //iamt_wdt is broken
	}
	return (WDIOF_MAGICCLOSE & watchDogInfo.options);
}

bool Watchdog::PrintWdtInfo()
{
	struct watchdog_info watchDogInfo;

	if (ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo) < 0) {
		Logmsg(LOG_ERR, "%s", MyStrerror(errno));
	} else {
		if (strcasecmp((const char*)watchDogInfo.identity, "software watchdog") != 0) {
			Logmsg(LOG_DEBUG, "Hardware watchdog '%s', version %u",
			       watchDogInfo.identity, watchDogInfo.firmware_version);
		} else {
			Logmsg(LOG_DEBUG, "%s, version %u",
			       watchDogInfo.identity, watchDogInfo.firmware_version);
		}
		dev dev;
		GetDeviceMajorMinor(&dev, (char*)path);
		Logmsg(LOG_DEBUG, "Device: %s Major: %li Minor: %li", path, dev.major, dev.minor);
		return true;
	}

	return false;
}

unsigned char * Watchdog::GetIdentity()
{
	static struct watchdog_info watchDogInfo;

	this->Ping();

	if (ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo) < 0) {
		Logmsg(LOG_ERR, "%s", MyStrerror(errno));
		return NULL;
	}

	return watchDogInfo.identity;
}

int Watchdog::Open(const char *const path)
{
	if (path == NULL) {
		return -1;
	}

	fd = open(path, O_WRONLY | O_CLOEXEC);

	if (fd == -1) {

		Logmsg(LOG_ERR,
		       "unable to open watchdog device: %s", MyStrerror(errno));
		return -1;
	}

	if (this->Ping() != 0) {
		Close();
		return -1;
	}

	if (CanMagicClose() == false) {
		Logmsg(LOG_ALERT,
		       "watchdog device does not support magic close char");
	}

	strcpy((char *)this->path, path);

	return 0;
}

int Watchdog::GetOptimalPingInterval()
{
	int timeout = 0;

	if (ioctl(fd, WDIOC_GETTIMEOUT, &timeout) < 0) {
		return 1;
	}

	timeout /= 2;

	if (timeout < 1 || timeout == 0)
		return 1;

	return timeout;
}

int Watchdog::Disable()
{
	int options = WDIOS_DISABLECARD;
	if (ioctl(fd, WDIOC_SETOPTIONS, &options) < 0) {
		Logmsg(LOG_CRIT, "WDIOS_DISABLECARD ioctl failed: %s",
		       MyStrerror(errno));
		return -1;
	}

	return 0;
}

int Watchdog::Enable()
{
	int options = WDIOS_ENABLECARD;
	if (ioctl(fd, WDIOC_SETOPTIONS, &options) < 0) {
		Logmsg(LOG_CRIT, "WDIOS_ENABLECARD ioctl failed: %s",
		       MyStrerror(errno));
		return -1;
	}

	return 0;
}

int Watchdog::ConfigureWatchdogTimeout(int timeout)
{
	struct watchdog_info watchDogInfo;

	if (timeout <= 0)
		return 0;

	if (Disable() < 0) {
		return -1;
	}

	if (ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo) < 0) {
		Logmsg(LOG_CRIT, "WDIOC_GETSUPPORT ioctl failed: %s",
		       MyStrerror(errno));
		return -1;
	}

	if (!(watchDogInfo.options & WDIOF_SETTIMEOUT)) {
		return -1;
	}

	int oldTimeout = timeout;

	if (ioctl(fd, WDIOC_SETTIMEOUT, &timeout) < 0) {
		this->timeout = GetOptimalPingInterval();

		fprintf(stderr, "watchdogd: unable to set WDT timeout\n");
		fprintf(stderr, "using default: %i", this->timeout);

		if (Enable() < 0) {
			return -1;
		}

		return Ping();
	}

	if (timeout != oldTimeout) {
		fprintf(stderr, "watchdogd: Actual WDT timeout: %i seconds\n",
			timeout);
		fprintf(stderr,
			"watchdogd: Timeout specified in the configuration file: %i\n",
			oldTimeout);
	}

	this->timeout = timeout;

	if (Enable() < 0) {
		return -1;
	}

	return Ping();
}

long unsigned Watchdog::GetStatus()
{
	long unsigned status = 0;

	ioctl(fd, WDIOC_GETBOOTSTATUS, &status);

	return status;
}

long Watchdog::GetFirmwareVersion()
{
	struct watchdog_info watchDogInfo = {0};

	ioctl(fd, WDIOC_GETSUPPORT, &watchDogInfo);

	return watchDogInfo.firmware_version;
}

long Watchdog::GetTimeleft()
{
	int timeleft = 0;

	if (ioctl(fd, WDIOC_GETTIMELEFT, &timeleft) < 0) {
		return -1;
	}

	return timeleft;
}

int Watchdog::GetRawTimeout()
{
	int timeout = 0;
	ioctl(fd, WDIOC_GETTIMEOUT, &timeout);
	return timeout;
}

bool Watchdog::CheckWatchdogTimeout(int timeout)
{
	if (timeout <= this->timeout) {
		return false;
	}
	return true;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <algorithm>

#include <boost/lexical_cast.hpp>

#include "Point.hpp"
#include "Function.hpp"
#include "SymbolicRegressionSolver.hpp"
#include "Config.hpp"

//#define VERBOSE_LOG

int amountOfSimulationsToPerform = 1;
SymbolicRegressionSolver::Config config{};
Function fn{parse("+ 1 x").statement, "x"};
int initialPoint = -10;
int endPoint = 10;
int stepSize = 2;

std::istream& operator>>(std::istream& is, SymbolicRegressionSolver::Config& config);
std::ostream& operator<<(std::ostream& os, const SymbolicRegressionSolver::Config& config);

void parseArguments(int argc, char *argv[]);
void printValidFlags()
{
    std::cout << "-c <configuration-file> (TODO)\n";
    std::cout << "-f <function>\n";
    std::cout << "-i <initial-point>\n";
    std::cout << "-e <end-point>\n";
    std::cout << "-s <step size>\n";
    std::cout << "-r <amount of times to redo simulation>\n";
}

void performSimulation(const PointList& points);

int main(int argc, char *argv[])
{
    parseArguments(argc, argv);

#ifdef VERBOSE_LOG
    std::clog << "function: " << fn << '\n';
    std::clog << "initial point: " << initialPoint << '\n';
    std::clog << "end point: " << endPoint << '\n';
    std::clog << "step size: " << stepSize << '\n';
#endif // VERBOSE_LOG

    std::vector<Point> points;
    points.reserve((endPoint - initialPoint)/stepSize);

    VariableMap map;
    for(int i = initialPoint; i <= endPoint; i += stepSize)
    {
        points.emplace_back(i, fn(map, i));
    }

    for(int i = 0; i < amountOfSimulationsToPerform; ++i)
    {
        performSimulation(points);
    }

    return 0;
}

void performSimulation(const PointList& points)
{
    SymbolicRegressionSolver solver(config, points);
    auto solutions = solver.solve();

    if(!solver.foundSolution())
    {
//        std::cout << "No solution!\n";
        return;
    }

    for(size_t i = 0; i < solutions.size(); ++i)
    {
        auto& solution = solutions[i];
        std::cout << solver.currentGeneration() << ",";
//        std::cout << i + 1 << ",";
        std::cout << solution.fitnessLevel << ",";
        std::cout << solution.mutated << ",";
        std::cout << solution.mated << '\n';

#ifdef VERBOSE_LOG
           std::cout << "solution " << i + 1 << ":\n";
           std::cout << "\tfunction: " << solution.function << '\n';
           std::cout << "\tfitness: " << solution.fitnessLevel << '\n';
           std::cout << "\tmutated?: " << std::boolalpha << solution.mutated << '\n';
           std::cout << "\tmated?: " << solution.mated << '\n';
#endif //VERBOSE_LOG
    }
}

void parseArguments(int argc, char *argv[])
{
    for(int i = 1; i < argc; ++i)
    {
        auto command = argv[i];
        auto commandSize = strlen(command);
        if(command[0] != '-')
        {
            std::cout << "Invalid format: " << command << ".\n";
            std::cout << "Flags must be prefixed with \"-\" (without quotes).\n";
            std::exit(-2);
            break;
        }

        if(commandSize == 1 || commandSize > 2)
        {
            std::cout << "Invalid flag: \"" << command << "\"\n";
            printValidFlags();
            std::exit(-5);
        }

        if(i + 1 >= argc)
        {
            std::cout << "please provide info with a flag...\n";
            printValidFlags();
            std::exit(-6);
        }

        switch(command[1])
        {
            // assign function
            case 'f':
                {
                    std::string functionAsString;
                    for(int j = i + 1; j < argc && argv[j][0] != '-'; ++j, ++i)
                    {
                        functionAsString += argv[j];
                    }
                    fn = functionAsString;
                }
                break;
            case 'i':
                {
                    std::string str = argv[++i];
                    initialPoint = boost::lexical_cast<int>(str);
                }
                break;
            case 'e':
                {
                    std::string str = argv[++i];
                    endPoint = boost::lexical_cast<int>(str);
                }
                break;
            case 's':
                {
                    std::string str = argv[++i];
                    stepSize = boost::lexical_cast<int>(str);
                }
                break;
            case 'r':
                {
                    std::string str = argv[++i];
                    amountOfSimulationsToPerform = boost::lexical_cast<int>(str);
                }
                break;
            case 'c':
                {
                    try
                    {
                        std::string filepath = argv[++i];
                        std::ifstream file;
                        file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
                        file.open(filepath);
                        file >> config; // read the config

                        /*
                        std::cout << "Loaded config:\n";
                        std::cout << config << std::endl;
                        */
                    }
                    catch(boost::bad_lexical_cast& e)
                    {
                        std::cerr << e.what();
                        std::exit(5);
                    }
                    catch(std::exception& e)
                    {
                        std::cerr << e.what();
                        std::exit(6);
                    }
                }
                break;
            default:
                std::cout << "Invalid flag\n";
                printValidFlags();
                std::exit(-4);
                break;
        }
    }
}

namespace
{
std::string obtainValue(const std::string& line)
{
    return std::string(line.begin() + line.find_last_of('=') + 1, line.end());
}

template <class T>
void read(std::string& buffer, std::istream& is, T& value)
{
    std::getline(is, buffer);
    auto stringValue = obtainValue(buffer);
    stringValue.erase(std::remove_if(stringValue.begin(), stringValue.end(), [](char c) { return std::isspace(c); }), stringValue.end());
    value = boost::lexical_cast<T>(stringValue);
}
}

std::ostream& operator<<(std::ostream& os, const SymbolicRegressionSolver::Config::NearestNeighbourOption& n)
{
    static constexpr const char* STRINGS[] = { "Always Use", "Never Use", "Random" };
    return os << STRINGS[static_cast<size_t>(n)];
}

std::ostream& operator<<(std::ostream& os, const SymbolicRegressionSolver::Config::PopulationRefillOption& p)
{
    static constexpr const char* STRINGS[] = { "Refill", "Duplicate", "Throw Away" };
    return os << STRINGS[static_cast<size_t>(p)];
}

std::ostream& operator<<(std::ostream& os, const SymbolicRegressionSolver::Config& config)
{
    os << "initial population = " << config.initialPopulation << '\n';
    os << "max generations    = " << config.maxGenerations << '\n';
    os << "initial max depth  = " << config.initialMaxDepth << '\n';
    os << "max solution depth = " << config.maxSolutionDepth << '\n';
    os << "keep percent       = " << config.keepPercentage << '\n';
    os << "mutation percent   = " << config.mutationPercent << '\n';
    os << "mate percent       = " << config.matePercent << '\n';
    os << "min constant       = " << config.constantDist.a() << '\n';
    os << "max constant       = " << config.constantDist.b() << '\n';
    os << "solution criteria  = " << config.solutionCriterea << '\n';
    os << "chance to change const = " << config.chanceToChangeConstant << '\n';
    os << "chance to change var = "  << config.chanceToChangeVar << '\n';
    os << "nearest neighbour opt = " << config.nearestNeighbourOption << '\n';
    os << "chance to use nearest neighbour = " << config.chanceToUseNearestNeighbour << '\n';
    os << "step size = " << config.stepSize << '\n';
    os << "pop refill opt = " << config.populationRefillOption << '\n';
    return os;
}

std::istream& operator>>(std::istream& is, SymbolicRegressionSolver::Config& config)
{
    std::string buffer;

    read(buffer, is, config.initialPopulation);
    read(buffer, is, config.maxGenerations);
    read(buffer, is, config.initialMaxDepth);
    read(buffer, is, config.maxSolutionDepth);
    read(buffer, is, config.keepPercentage);
    read(buffer, is, config.mutationPercent);
    read(buffer, is, config.matePercent);

    // have to do this separately for const dist
    int a, b;
    read(buffer, is, a);
    read(buffer, is, b);

    config.constantDist = decltype(config.constantDist){a, b};

    read(buffer, is, config.solutionCriterea);
    read(buffer, is, config.chanceToChangeConstant);
    read(buffer, is, config.chanceToChangeVar);

    int nearestNeighbour = 0;
    read(buffer, is, nearestNeighbour);
    config.nearestNeighbourOption = static_cast<decltype(config.nearestNeighbourOption)>(nearestNeighbour);

    read(buffer, is, config.chanceToUseNearestNeighbour);
    read(buffer, is, config.stepSize);

    int refillOption = 0;
    read(buffer, is, refillOption);
    config.populationRefillOption = static_cast<decltype(config.populationRefillOption)>(refillOption);

    return is;
}
<commit_msg>Fixed segfault in CLI<commit_after>#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <algorithm>

#include <boost/lexical_cast.hpp>

#include "Point.hpp"
#include "Function.hpp"
#include "SymbolicRegressionSolver.hpp"
#include "Config.hpp"

//#define VERBOSE_LOG

int amountOfSimulationsToPerform = 1;
SymbolicRegressionSolver::Config config{};
Function fn{parse("+ 1 x").statement, "x"};
int initialPoint = -10;
int endPoint = 10;
int stepSize = 2;

std::istream& operator>>(std::istream& is, SymbolicRegressionSolver::Config& config);
std::ostream& operator<<(std::ostream& os, const SymbolicRegressionSolver::Config& config);

void parseArguments(int argc, char *argv[]);
void printValidFlags()
{
    std::cout << "-c <configuration-file> (TODO)\n";
    std::cout << "-f <function>\n";
    std::cout << "-i <initial-point>\n";
    std::cout << "-e <end-point>\n";
    std::cout << "-s <step size>\n";
    std::cout << "-r <amount of times to redo simulation>\n";
}

void performSimulation(const PointList& points);

int main(int argc, char *argv[])
{
    parseArguments(argc, argv);

#ifdef VERBOSE_LOG
    std::clog << "function: " << fn << '\n';
    std::clog << "initial point: " << initialPoint << '\n';
    std::clog << "end point: " << endPoint << '\n';
    std::clog << "step size: " << stepSize << '\n';
#endif // VERBOSE_LOG

    std::vector<Point> points;
    points.reserve((endPoint - initialPoint)/stepSize);

    VariableMap map;
    for(int i = initialPoint; i <= endPoint; i += stepSize)
    {
        points.emplace_back(i, fn(map, i));
    }

    for(int i = 0; i < amountOfSimulationsToPerform; ++i)
    {
        performSimulation(points);
    }

    return 0;
}

void performSimulation(const PointList& points)
{
    SymbolicRegressionSolver solver(config, points);
    auto solutions = solver.solve();

    if(!solver.foundSolution())
    {
//        std::cout << "No solution!\n";
        return;
    }

    for(size_t i = 0; i < solutions.size(); ++i)
    {
        auto& solution = solutions[i];
        std::cout << solver.currentGeneration() << ",";
//        std::cout << i + 1 << ",";
        std::cout << solution.fitnessLevel << ",";
        std::cout << solution.mutated << ",";
        std::cout << solution.mated << '\n';

#ifdef VERBOSE_LOG
           std::cout << "solution " << i + 1 << ":\n";
           std::cout << "\tfunction: " << solution.function << '\n';
           std::cout << "\tfitness: " << solution.fitnessLevel << '\n';
           std::cout << "\tmutated?: " << std::boolalpha << solution.mutated << '\n';
           std::cout << "\tmated?: " << solution.mated << '\n';
#endif //VERBOSE_LOG
    }
}

void parseArguments(int argc, char *argv[])
{
    for(int i = 1; i < argc; ++i)
    {
        auto command = argv[i];
        auto commandSize = strlen(command);
        if(command[0] != '-')
        {
            std::cout << "Invalid format: " << command << ".\n";
            std::cout << "Flags must be prefixed with \"-\" (without quotes).\n";
            std::exit(-2);
            break;
        }

        if(commandSize == 1 || commandSize > 2)
        {
            std::cout << "Invalid flag: \"" << command << "\"\n";
            printValidFlags();
            std::exit(-5);
        }

        if(i + 1 >= argc)
        {
            std::cout << "please provide info with a flag...\n";
            printValidFlags();
            std::exit(-6);
        }

        switch(command[1])
        {
            // assign function
            case 'f':
                {
                    std::string functionAsString;
                    for(int j = i + 1; j < argc && argv[j][0] != '-'; ++j, ++i)
                    {
                        functionAsString += argv[j];
                    }
                    fn = functionAsString;
                    fn = parse(functionAsString).statement;
                }
                break;
            case 'i':
                {
                    std::string str = argv[++i];
                    initialPoint = boost::lexical_cast<int>(str);
                }
                break;
            case 'e':
                {
                    std::string str = argv[++i];
                    endPoint = boost::lexical_cast<int>(str);
                }
                break;
            case 's':
                {
                    std::string str = argv[++i];
                    stepSize = boost::lexical_cast<int>(str);
                }
                break;
            case 'r':
                {
                    std::string str = argv[++i];
                    amountOfSimulationsToPerform = boost::lexical_cast<int>(str);
                }
                break;
            case 'c':
                {
                    try
                    {
                        std::string filepath = argv[++i];
                        std::ifstream file;
                        file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
                        file.open(filepath);
                        file >> config; // read the config

                        /*
                        std::cout << "Loaded config:\n";
                        std::cout << config << std::endl;
                        */
                    }
                    catch(boost::bad_lexical_cast& e)
                    {
                        std::cerr << e.what();
                        std::exit(5);
                    }
                    catch(std::exception& e)
                    {
                        std::cerr << e.what();
                        std::exit(6);
                    }
                }
                break;
            default:
                std::cout << "Invalid flag\n";
                printValidFlags();
                std::exit(-4);
                break;
        }
    }
}

namespace
{
std::string obtainValue(const std::string& line)
{
    return std::string(line.begin() + line.find_last_of('=') + 1, line.end());
}

template <class T>
void read(std::string& buffer, std::istream& is, T& value)
{
    std::getline(is, buffer);
    auto stringValue = obtainValue(buffer);
    stringValue.erase(std::remove_if(stringValue.begin(), stringValue.end(), [](char c) { return std::isspace(c); }), stringValue.end());
    value = boost::lexical_cast<T>(stringValue);
}
}

std::ostream& operator<<(std::ostream& os, const SymbolicRegressionSolver::Config::NearestNeighbourOption& n)
{
    static constexpr const char* STRINGS[] = { "Always Use", "Never Use", "Random" };
    return os << STRINGS[static_cast<size_t>(n)];
}

std::ostream& operator<<(std::ostream& os, const SymbolicRegressionSolver::Config::PopulationRefillOption& p)
{
    static constexpr const char* STRINGS[] = { "Refill", "Duplicate", "Throw Away" };
    return os << STRINGS[static_cast<size_t>(p)];
}

std::ostream& operator<<(std::ostream& os, const SymbolicRegressionSolver::Config& config)
{
    os << "initial population = " << config.initialPopulation << '\n';
    os << "max generations    = " << config.maxGenerations << '\n';
    os << "initial max depth  = " << config.initialMaxDepth << '\n';
    os << "max solution depth = " << config.maxSolutionDepth << '\n';
    os << "keep percent       = " << config.keepPercentage << '\n';
    os << "mutation percent   = " << config.mutationPercent << '\n';
    os << "mate percent       = " << config.matePercent << '\n';
    os << "min constant       = " << config.constantDist.a() << '\n';
    os << "max constant       = " << config.constantDist.b() << '\n';
    os << "solution criteria  = " << config.solutionCriterea << '\n';
    os << "chance to change const = " << config.chanceToChangeConstant << '\n';
    os << "chance to change var = "  << config.chanceToChangeVar << '\n';
    os << "nearest neighbour opt = " << config.nearestNeighbourOption << '\n';
    os << "chance to use nearest neighbour = " << config.chanceToUseNearestNeighbour << '\n';
    os << "step size = " << config.stepSize << '\n';
    os << "pop refill opt = " << config.populationRefillOption << '\n';
    return os;
}

std::istream& operator>>(std::istream& is, SymbolicRegressionSolver::Config& config)
{
    std::string buffer;

    read(buffer, is, config.initialPopulation);
    read(buffer, is, config.maxGenerations);
    read(buffer, is, config.initialMaxDepth);
    read(buffer, is, config.maxSolutionDepth);
    read(buffer, is, config.keepPercentage);
    read(buffer, is, config.mutationPercent);
    read(buffer, is, config.matePercent);

    // have to do this separately for const dist
    int a, b;
    read(buffer, is, a);
    read(buffer, is, b);

    config.constantDist = decltype(config.constantDist){a, b};

    read(buffer, is, config.solutionCriterea);
    read(buffer, is, config.chanceToChangeConstant);
    read(buffer, is, config.chanceToChangeVar);

    int nearestNeighbour = 0;
    read(buffer, is, nearestNeighbour);
    config.nearestNeighbourOption = static_cast<decltype(config.nearestNeighbourOption)>(nearestNeighbour);

    read(buffer, is, config.chanceToUseNearestNeighbour);
    read(buffer, is, config.stepSize);

    int refillOption = 0;
    read(buffer, is, refillOption);
    config.populationRefillOption = static_cast<decltype(config.populationRefillOption)>(refillOption);

    return is;
}
<|endoftext|>


<commit_before><commit_msg>prob2 fast algo<commit_after><|endoftext|>