<commit_before>/*  Copyright 2014 Aaron Boxer

    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/>. */

#pragma once

#include "OCLDWT.h"
#include "OCLMemoryManager.h"
#include <stdint.h>

inline int divRndUp(const int n, const int d) {
	return n/d + !!(n % d);
  }

template<typename T> OCLDWT<T>::OCLDWT(KernelInitInfoBase initInfo, OCLMemoryManager<T>* memMgr) :
	                initInfo(initInfo),
					memoryManager(memMgr),
					forward53(new OCLKernel( KernelInitInfo(initInfo, "ocldwt53.cl", "run") )),
					forward97(new OCLKernel( KernelInitInfo(initInfo, "ocldwt97.cl", "run") ))

{
}

template<typename T> OCLDWT<T>::~OCLDWT(void)
{
	if (forward53)
		delete forward53;
	if (forward97)
		delete forward97;
}

template<typename T> void OCLDWT<T>::encode(bool lossy, std::vector<T*> components,	int w,	int h, int windowX, int windowY) {

	if (components.size() == 0)
		return;
	if (lossy) {
		OCLKernel* targetKernel = forward97;
		memoryManager->init(components,w,h,lossy);
		const int steps = divRndUp(h, 15 * windowY);
		setKernelArgs(targetKernel,steps);

		size_t global_offset[3] = {-2,0,0};   //left boundary

		//add one extra windowX to make up for group overlap due to boundary
	   size_t global_work_size[3] = {(divRndUp(w, windowX) + 1)* windowX, divRndUp(h, windowY * steps),1};
	   size_t local_work_size[3] = {windowX,1,1};

	   targetKernel->enqueue(2,global_offset, global_work_size, local_work_size);

	} else {
		OCLKernel* targetKernel = forward53;
		memoryManager->init(components,w,h,lossy);
		const int steps = divRndUp(h, 15 * windowY);
		setKernelArgs(targetKernel,steps);

		size_t global_offset[3] = {-2,0,0};   //left boundary

		//add one extra windowX to make up for group overlap due to boundary
	   size_t global_work_size[3] = {(divRndUp(w, windowX) + 1)* windowX, divRndUp(h, windowY * steps),1};
	   size_t local_work_size[3] = {windowX,1,1};

	  targetKernel->enqueue(2,global_offset, global_work_size, local_work_size);

	}
}

template<typename T> tDeviceRC OCLDWT<T>::setKernelArgs(OCLKernel* myKernel,int steps){

	cl_int error_code =  DeviceSuccess;
	cl_kernel targetKernel = myKernel->getKernel();
	int argNum = 0;
	unsigned int width = (unsigned int)memoryManager->getWidth();
	unsigned int height = (unsigned int)memoryManager->getHeight();

	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(cl_mem),  memoryManager->getPreprocessOut());
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}

	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(cl_mem), memoryManager->getDwtOut());
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}
	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(width), &width);
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}
	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(height), &height);
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}
	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(steps), &steps);
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}
	return DeviceSuccess;
}

<commit_msg>corrected initial work item offset for lossy<commit_after>/*  Copyright 2014 Aaron Boxer

    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/>. */

#pragma once

#include "OCLDWT.h"
#include "OCLMemoryManager.h"
#include <stdint.h>

inline int divRndUp(const int n, const int d) {
	return n/d + !!(n % d);
  }

template<typename T> OCLDWT<T>::OCLDWT(KernelInitInfoBase initInfo, OCLMemoryManager<T>* memMgr) :
	                initInfo(initInfo),
					memoryManager(memMgr),
					forward53(new OCLKernel( KernelInitInfo(initInfo, "ocldwt53.cl", "run") )),
					forward97(new OCLKernel( KernelInitInfo(initInfo, "ocldwt97.cl", "run") ))

{
}

template<typename T> OCLDWT<T>::~OCLDWT(void)
{
	if (forward53)
		delete forward53;
	if (forward97)
		delete forward97;
}

template<typename T> void OCLDWT<T>::encode(bool lossy, std::vector<T*> components,	int w,	int h, int windowX, int windowY) {

	if (components.size() == 0)
		return;
	if (lossy) {
		OCLKernel* targetKernel = forward97;
		memoryManager->init(components,w,h,lossy);
		const int steps = divRndUp(h, 15 * windowY);
		setKernelArgs(targetKernel,steps);

		size_t global_offset[3] = {-4,0,0};   //left boundary

		//add one extra windowX to make up for group overlap due to boundary
	   size_t global_work_size[3] = {(divRndUp(w, windowX) + 1)* windowX, divRndUp(h, windowY * steps),1};
	   size_t local_work_size[3] = {windowX,1,1};

	   targetKernel->enqueue(2,global_offset, global_work_size, local_work_size);

	} else {
		OCLKernel* targetKernel = forward53;
		memoryManager->init(components,w,h,lossy);
		const int steps = divRndUp(h, 15 * windowY);
		setKernelArgs(targetKernel,steps);

		size_t global_offset[3] = {-2,0,0};   //left boundary

		//add one extra windowX to make up for group overlap due to boundary
	   size_t global_work_size[3] = {(divRndUp(w, windowX) + 1)* windowX, divRndUp(h, windowY * steps),1};
	   size_t local_work_size[3] = {windowX,1,1};

	  targetKernel->enqueue(2,global_offset, global_work_size, local_work_size);

	}
}

template<typename T> tDeviceRC OCLDWT<T>::setKernelArgs(OCLKernel* myKernel,int steps){

	cl_int error_code =  DeviceSuccess;
	cl_kernel targetKernel = myKernel->getKernel();
	int argNum = 0;
	unsigned int width = (unsigned int)memoryManager->getWidth();
	unsigned int height = (unsigned int)memoryManager->getHeight();

	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(cl_mem),  memoryManager->getPreprocessOut());
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}

	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(cl_mem), memoryManager->getDwtOut());
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}
	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(width), &width);
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}
	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(height), &height);
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}
	error_code = clSetKernelArg(targetKernel, argNum++, sizeof(steps), &steps);
	if (DeviceSuccess != error_code)
	{
		LogError("Error: setKernelArgs returned %s.\n", TranslateOpenCLError(error_code));
		return error_code;
	}
	return DeviceSuccess;
}

<|endoftext|>


<commit_before>#include "Player.h"
/*
namespace Blackjack
{
	class Player
	{//A Blackjack player.
		private:
			std::vector<Hand> hands;//Put the hand in a vector since there could be more than one due to a split.

		public:
			Player();//Default Cunstructor.
			size_t numHands() const;//Returns the number of hands the player currently has.
			Hand& getHand( size_t n );//Returns the hand at location n. n should be between 0 and numHands()-1, inclusive.
			std::vector<Hand>& getHands();//Returns the hands as a vector. This is mainly for use with HandsIterator.
			void split( size_t n );//Splits the hand at index n. Throws an exception if the hand can't be split according to the rules of blackjack.
	};
}
*/

namespace Blackjack
{
	Player::Player()
	{//Default Cunstructor.
	}

	size_t Player::numHands() const
	{//Returns the number of hands the player currently has.
		return hands.size();
	}

	Hand& getHand( size_t n )
	{//Returns the hand at location n. n should be between 0 and numHands()-1, inclusive.
		return hands.at(n);
	}
}
<commit_msg>Added a couple method definitions.<commit_after>#include "Player.h"
/*
namespace Blackjack
{
	class Player
	{//A Blackjack player.
		private:
			std::vector<Hand> hands;//Put the hand in a vector since there could be more than one due to a split.

		public:
			Player();//Default Cunstructor.
			size_t numHands() const;//Returns the number of hands the player currently has.
			Hand& getHand( size_t n );//Returns the hand at location n. n should be between 0 and numHands()-1, inclusive.
			std::vector<Hand>& getHands();//Returns the hands as a vector. This is mainly for use with HandsIterator.
			void split( size_t n );//Splits the hand at index n. Throws an exception if the hand can't be split according to the rules of blackjack.
	};
}
*/

namespace Blackjack
{
	Player::Player()
	{//Default Cunstructor.
	}

	size_t Player::numHands() const
	{//Returns the number of hands the player currently has.
		return hands.size();
	}

	Hand& getHand( size_t n )
	{//Returns the hand at location n. n should be between 0 and numHands()-1, inclusive.
		return hands.at(n);
	}

	std::vector<Hand>& getHands()
	{//Returns the hands as a vector. This is mainly for use with HandsIterator.
	}

	void split( size_t n )
	{//Splits the hand at index n. Throws an exception if the hand can't be split according to the rules of blackjack.
	}
}
<|endoftext|>


<commit_before>#include "Player.h"
#include "SDL.h"

Player::Player(const LoaderParams* pParams) : SDLGameObject(pParams) { }

void Player::draw()
{
	SDLGameObject::draw();	//we now use SDLGameObject
}

void Player::update()
{
	m_currentFrame = int(((SDL_GetTicks() / 100) % 6));

	m_velocity.setX(1);

	SDLGameObject::update();
}

void Player::clean()
{
	//blank clean() function
}<commit_msg>Player's update() now uses accelaration vector instead of velocity vector<commit_after>#include "Player.h"
#include "SDL.h"

Player::Player(const LoaderParams* pParams) : SDLGameObject(pParams) { }

void Player::draw()
{
	SDLGameObject::draw();	//we now use SDLGameObject
}

void Player::update()
{
	m_currentFrame = int(((SDL_GetTicks() / 100) % 6));

	m_accelaration.setX(1);

	SDLGameObject::update();
}

void Player::clean()
{
	//blank clean() function
}<|endoftext|>


<commit_before>// Copyright (c) 2018 Matthew J. Smith and Overkit contributors
// License: MIT (http://opensource.org/licenses/MIT)

#ifndef OVK_CORE_TYPE_TRAITS_HPP_INCLUDED
#define OVK_CORE_TYPE_TRAITS_HPP_INCLUDED

#include <ovk/core/Global.hpp>

#include <type_traits>

namespace ovk {
namespace core {

// Apply const & reference qualifiers of one type to another type
namespace mimicked_ref_internal {
template <typename T, typename U> struct helper {
  using type = U;
};
template <typename T, typename U> struct helper<T &, U> {
  using type = typename std::add_lvalue_reference<U>::type;
};
template <typename T, typename U> struct helper<const T &, U> {
  using type = typename std::add_lvalue_reference<typename std::add_const<U>::type>::type;
};
template <typename T, typename U> struct helper<T &&, U> {
  using type = typename std::add_rvalue_reference<U>::type;
};
template <typename T, typename U> struct helper<const T &&, U> {
  using type = typename std::add_rvalue_reference<typename std::add_const<U>::type>::type;
};
}
template <typename T, typename U> using mimicked_ref = typename mimicked_ref_internal::helper<T,
U>::type;

}}

#endif
<commit_msg>added helper for stripping cv and reference qualifiers from a type<commit_after>// Copyright (c) 2018 Matthew J. Smith and Overkit contributors
// License: MIT (http://opensource.org/licenses/MIT)

#ifndef OVK_CORE_TYPE_TRAITS_HPP_INCLUDED
#define OVK_CORE_TYPE_TRAITS_HPP_INCLUDED

#include <ovk/core/Global.hpp>

#include <type_traits>

namespace ovk {
namespace core {

// Remove cv and reference qualifiers
template <typename T> using remove_cvref = typename std::remove_cv<typename std::remove_reference<T
  >::type>::type;

// Apply const & reference qualifiers of one type to another type
namespace mimicked_ref_internal {
template <typename T, typename U> struct helper {
  using type = U;
};
template <typename T, typename U> struct helper<T &, U> {
  using type = typename std::add_lvalue_reference<U>::type;
};
template <typename T, typename U> struct helper<const T &, U> {
  using type = typename std::add_lvalue_reference<typename std::add_const<U>::type>::type;
};
template <typename T, typename U> struct helper<T &&, U> {
  using type = typename std::add_rvalue_reference<U>::type;
};
template <typename T, typename U> struct helper<const T &&, U> {
  using type = typename std::add_rvalue_reference<typename std::add_const<U>::type>::type;
};
}
template <typename T, typename U> using mimicked_ref = typename mimicked_ref_internal::helper<T,
U>::type;

}}

#endif
<|endoftext|>


<commit_before>// This file is part of the AliceVision project and is made available under
// the terms of the MPL2 license (see the COPYING.md file).

#include "aliceVision/sfm/sfm.hpp"
#include "aliceVision/image/image.hpp"

#include "dependencies/cmdLine/cmdLine.h"

#include <boost/progress.hpp>

#include <stdlib.h>

using namespace aliceVision;
using namespace aliceVision::camera;
using namespace aliceVision::geometry;
using namespace aliceVision::image;
using namespace aliceVision::sfm;

int main(int argc, char *argv[])
{
  CmdLine cmd;
  std::string sSfMData_Filename;
  std::string sOutDir = "";

  cmd.add( make_option('i', sSfMData_Filename, "sfmdata") );
  cmd.add( make_option('o', sOutDir, "outdir") );

  try {
      if (argc == 1) throw std::string("Invalid command line parameter.");
      cmd.process(argc, argv);
  } catch(const std::string& s) {
    std::cerr
      << "Export undistorted images related to a sfm_data file.\n"
      << "Usage: " << argv[0] << '\n'
      << "[-i|--sfmdata] filename, the SfMData file to convert\n"
      << "[-o|--outdir] path\n"
      << std::endl;

      std::cerr << s << std::endl;
      return EXIT_FAILURE;
  }

  // Create output dir
  if (!stlplus::folder_exists(sOutDir))
    stlplus::folder_create( sOutDir );

  SfMData sfm_data;
  if (!Load(sfm_data, sSfMData_Filename, ESfMData(VIEWS|INTRINSICS))) {
    std::cerr << std::endl
      << "The input SfMData file \""<< sSfMData_Filename << "\" cannot be read." << std::endl;
    return EXIT_FAILURE;
  }

  bool bOk = true;
  {
    // Export views as undistorted images (those with valid Intrinsics)
    Image<RGBColor> image, image_ud;
    boost::progress_display my_progress_bar( sfm_data.GetViews().size() );
    for(Views::const_iterator iter = sfm_data.GetViews().begin();
      iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar)
    {
      const View * view = iter->second.get();
      bool bIntrinsicDefined = view->getIntrinsicId() != UndefinedIndexT &&
        sfm_data.GetIntrinsics().find(view->getIntrinsicId()) != sfm_data.GetIntrinsics().end();

      Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->getIntrinsicId());

      const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->getImagePath());
      const std::string dstImage = stlplus::create_filespec(
        sOutDir, stlplus::filename_part(srcImage));

      const IntrinsicBase * cam = iterIntrinsic->second.get();
      if (cam->isValid() && cam->have_disto())
      {
        // undistort the image and save it
        if (ReadImage( srcImage.c_str(), &image))
        {
          UndistortImage(image, cam, image_ud, BLACK);
          bOk &= WriteImage(dstImage.c_str(), image_ud);
        }
      }
      else // (no distortion)
      {
        // copy the image since there is no distortion
        stlplus::file_copy(srcImage, dstImage);
      }
    }
  }

  // Exit program
  if (bOk)
    return( EXIT_SUCCESS );
  else
    return( EXIT_FAILURE );
}
<commit_msg>[software] exportUndistortedImages use boost program options<commit_after>// This file is part of the AliceVision project and is made available under
// the terms of the MPL2 license (see the COPYING.md file).

#include "aliceVision/sfm/sfm.hpp"
#include "aliceVision/image/image.hpp"

#include <boost/program_options.hpp>
#include <boost/progress.hpp>

#include <stdlib.h>

using namespace aliceVision;
using namespace aliceVision::camera;
using namespace aliceVision::geometry;
using namespace aliceVision::image;
using namespace aliceVision::sfm;
namespace po = boost::program_options;

int main(int argc, char *argv[])
{
  // command-line parameters

  std::string verboseLevel = system::EVerboseLevel_enumToString(system::Logger::getDefaultVerboseLevel());
  std::string sfmDataFilename;
  std::string outDirectory;

  po::options_description allParams(
    "Export undistorted images related to a sfm_data file.\n"
    "AliceVision exportUndistortedImages");

  po::options_description requiredParams("Required parameters");
  requiredParams.add_options()
    ("input,i", po::value<std::string>(&sfmDataFilename)->required(),
      "SfMData file.")
    ("output,o", po::value<std::string>(&outDirectory)->required(),
      "Output directory.");

  po::options_description logParams("Log parameters");
  logParams.add_options()
    ("verboseLevel,v", po::value<std::string>(&verboseLevel)->default_value(verboseLevel),
      "verbosity level (fatal,  error, warning, info, debug, trace).");

  allParams.add(requiredParams).add(logParams);

  po::variables_map vm;
  try
  {
    po::store(po::parse_command_line(argc, argv, allParams), vm);

    if(vm.count("help") || (argc == 1))
    {
      ALICEVISION_COUT(allParams);
      return EXIT_SUCCESS;
    }
    po::notify(vm);
  }
  catch(boost::program_options::required_option& e)
  {
    ALICEVISION_CERR("ERROR: " << e.what());
    ALICEVISION_COUT("Usage:\n\n" << allParams);
    return EXIT_FAILURE;
  }
  catch(boost::program_options::error& e)
  {
    ALICEVISION_CERR("ERROR: " << e.what());
    ALICEVISION_COUT("Usage:\n\n" << allParams);
    return EXIT_FAILURE;
  }

  // set verbose level
  system::Logger::get()->setLogLevel(verboseLevel);

  // Create output dir
  if (!stlplus::folder_exists(outDirectory))
    stlplus::folder_create( outDirectory );

  SfMData sfm_data;
  if (!Load(sfm_data, sfmDataFilename, ESfMData(VIEWS|INTRINSICS))) {
    std::cerr << std::endl
      << "The input SfMData file \""<< sfmDataFilename << "\" cannot be read." << std::endl;
    return EXIT_FAILURE;
  }

  bool bOk = true;
  {
    // Export views as undistorted images (those with valid Intrinsics)
    Image<RGBColor> image, image_ud;
    boost::progress_display my_progress_bar( sfm_data.GetViews().size() );
    for(Views::const_iterator iter = sfm_data.GetViews().begin();
      iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar)
    {
      const View * view = iter->second.get();
      bool bIntrinsicDefined = view->getIntrinsicId() != UndefinedIndexT &&
        sfm_data.GetIntrinsics().find(view->getIntrinsicId()) != sfm_data.GetIntrinsics().end();

      Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->getIntrinsicId());

      const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->getImagePath());
      const std::string dstImage = stlplus::create_filespec(
        outDirectory, stlplus::filename_part(srcImage));

      const IntrinsicBase * cam = iterIntrinsic->second.get();
      if (cam->isValid() && cam->have_disto())
      {
        // undistort the image and save it
        if (ReadImage( srcImage.c_str(), &image))
        {
          UndistortImage(image, cam, image_ud, BLACK);
          bOk &= WriteImage(dstImage.c_str(), image_ud);
        }
      }
      else // (no distortion)
      {
        // copy the image since there is no distortion
        stlplus::file_copy(srcImage, dstImage);
      }
    }
  }

  // Exit program
  if (bOk)
    return( EXIT_SUCCESS );
  else
    return( EXIT_FAILURE );
}
<|endoftext|>


<commit_before>//: ----------------------------------------------------------------------------
//: Copyright (C) 2016 Verizon.  All Rights Reserved.
//: All Rights Reserved
//:
//: \file:    lookup_inline.cc
//: \details: TODO
//: \author:  Reed P. Morrison
//: \date:    02/16/2016
//:
//:   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.
//:
//: ----------------------------------------------------------------------------
//: ----------------------------------------------------------------------------
//: Includes
//: ----------------------------------------------------------------------------
#include "support/time_util.h"
#include "support/ndebug.h"
#include "dns/nlookup.h"
#include "nconn/host_info.h"
#include "status.h"
#include <unistd.h>
#include <netdb.h>
#include <string.h>
// for inet_pton
#include <arpa/inet.h>
namespace ns_hurl {
//: ----------------------------------------------------------------------------
//: \details: slow resolution
//: \return:  TODO
//: \param:   TODO
//: ----------------------------------------------------------------------------
int32_t nlookup(const std::string &a_host, uint16_t a_port, host_info &ao_host_info, int g_ai_family)
{
        //NDBG_PRINT("%sRESOLVE%s: a_host: %s a_port: %d\n",
        //           ANSI_COLOR_BG_RED, ANSI_COLOR_OFF,
        //           a_host.c_str(), a_port);
        // Initialize...
        ao_host_info.m_sa_len = sizeof(ao_host_info.m_sa);
        memset((void*) &(ao_host_info.m_sa), 0, ao_host_info.m_sa_len);
        // ---------------------------------------
        // get address...
        // ---------------------------------------
        struct addrinfo l_hints;
        memset(&l_hints, 0, sizeof(l_hints));
        l_hints.ai_family = g_ai_family;
        l_hints.ai_socktype = SOCK_STREAM;
        char portstr[10];
        snprintf(portstr, sizeof(portstr), "%d", (int) a_port);
        struct addrinfo* l_addrinfo;
        int l_gaierr;
        l_gaierr = getaddrinfo(a_host.c_str(), portstr, &l_hints, &l_addrinfo);
        if (l_gaierr != 0)
        {
                //NDBG_PRINT("Error getaddrinfo '%s': %s\n",
                //           a_host.c_str(), gai_strerror(l_gaierr));
                return STATUS_ERROR;
        }
        // Find the first IPv4 and IPv6 entries.
        struct addrinfo* l_addrinfo_v4 = NULL;
        struct addrinfo* l_addrinfo_v6 = NULL;
        for (struct addrinfo* i_addrinfo = l_addrinfo;
             i_addrinfo != (struct addrinfo*) 0;
             i_addrinfo = i_addrinfo->ai_next)
        {
                switch (i_addrinfo->ai_family)
                {
                case AF_INET:
                {
                        if (l_addrinfo_v4 == (struct addrinfo*) 0)
                                l_addrinfo_v4 = i_addrinfo;
                        break;
                }
                case AF_INET6:
                {
                        if (l_addrinfo_v6 == (struct addrinfo*) 0)
                                l_addrinfo_v6 = i_addrinfo;
                        break;
                }
                }
        }
        //NDBG_PRINT("RESOLVE:\n");
        // If there's an IPv4 address, use that, otherwise try IPv6.
        if (l_addrinfo_v4 != NULL)
        {
                if (sizeof(ao_host_info.m_sa) < l_addrinfo_v4->ai_addrlen)
                {
                        NDBG_PRINT("Error %s - sockaddr too small (%lu < %lu)\n",
                                   a_host.c_str(),
                              (unsigned long) sizeof(ao_host_info.m_sa),
                              (unsigned long) l_addrinfo_v4->ai_addrlen);
                        return STATUS_ERROR;
                }
                ao_host_info.m_sock_family = l_addrinfo_v4->ai_family;
                ao_host_info.m_sock_type = l_addrinfo_v4->ai_socktype;
                ao_host_info.m_sock_protocol = l_addrinfo_v4->ai_protocol;
                ao_host_info.m_sa_len = l_addrinfo_v4->ai_addrlen;
                //NDBG_PRINT("memmove: addrlen: %d\n", l_addrinfo_v4->ai_addrlen);
                //ns_hurl::mem_display((const uint8_t *)l_addrinfo_v4->ai_addr,
                //                   l_addrinfo_v4->ai_addrlen);
                //show_host_info();
                memmove(&(ao_host_info.m_sa),
                        l_addrinfo_v4->ai_addr,
                        l_addrinfo_v4->ai_addrlen);
                // Set the port
                ((sockaddr_in *)(&(ao_host_info.m_sa)))->sin_port = htons(a_port);
                freeaddrinfo(l_addrinfo);
        }
        else if (l_addrinfo_v6 != NULL)
        {
                if (sizeof(ao_host_info.m_sa) < l_addrinfo_v6->ai_addrlen)
                {
                        NDBG_PRINT("Error %s - sockaddr too small (%lu < %lu)\n",
                                   a_host.c_str(),
                              (unsigned long) sizeof(ao_host_info.m_sa),
                              (unsigned long) l_addrinfo_v6->ai_addrlen);
                        return STATUS_ERROR;
                }
                ao_host_info.m_sock_family = l_addrinfo_v6->ai_family;
                ao_host_info.m_sock_type = l_addrinfo_v6->ai_socktype;
                ao_host_info.m_sock_protocol = l_addrinfo_v6->ai_protocol;
                ao_host_info.m_sa_len = l_addrinfo_v6->ai_addrlen;
                //NDBG_PRINT("memmove: addrlen: %d\n", l_addrinfo_v6->ai_addrlen);
                //ns_hurl::mem_display((const uint8_t *)l_addrinfo_v6->ai_addr,
                //                    l_addrinfo_v6->ai_addrlen);
                //show_host_info();
                memmove(&ao_host_info.m_sa,
                        l_addrinfo_v6->ai_addr,
                        l_addrinfo_v6->ai_addrlen);
                // Set the port
                ((sockaddr_in6 *)(&(ao_host_info.m_sa)))->sin6_port = htons(a_port);
                freeaddrinfo(l_addrinfo);
        }
        else
        {
                NDBG_PRINT("Error no valid address found for host %s\n",
                           a_host.c_str());
                return STATUS_ERROR;
        }
        // Set to 60min -cuz getaddr-info stinks...
        ao_host_info.m_expires_s = get_time_s() + 3600;
        return STATUS_OK;
}
}
<commit_msg>fixing hostname resolution.<commit_after>//: ----------------------------------------------------------------------------
//: Copyright (C) 2016 Verizon.  All Rights Reserved.
//: All Rights Reserved
//:
//: \file:    lookup_inline.cc
//: \details: TODO
//: \author:  Reed P. Morrison
//: \date:    02/16/2016
//:
//:   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.
//:
//: ----------------------------------------------------------------------------
//: ----------------------------------------------------------------------------
//: Includes
//: ----------------------------------------------------------------------------
#include "support/time_util.h"
#include "support/ndebug.h"
#include "dns/nlookup.h"
#include "nconn/host_info.h"
#include "status.h"
#include <unistd.h>
#include <netdb.h>
#include <string.h>
// for inet_pton
#include <arpa/inet.h>
namespace ns_hurl {
//: ----------------------------------------------------------------------------
//: \details: slow resolution
//: \return:  TODO
//: \param:   TODO
//: ----------------------------------------------------------------------------
int32_t nlookup(const std::string &a_host,
                uint16_t a_port,
                host_info &ao_host_info,
                int a_ai_family)
{
        //NDBG_PRINT("%sRESOLVE%s: a_host: %s a_port: %d\n",
        //           ANSI_COLOR_BG_RED, ANSI_COLOR_OFF,
        //           a_host.c_str(), a_port);
        // Initialize...
        ao_host_info.m_sa_len = sizeof(ao_host_info.m_sa);
        memset((void*) &(ao_host_info.m_sa), 0, ao_host_info.m_sa_len);
        // ---------------------------------------
        // get address...
        // ---------------------------------------
        struct addrinfo l_hints;
        memset(&l_hints, 0, sizeof(l_hints));
        l_hints.ai_family = a_ai_family;
        l_hints.ai_socktype = SOCK_STREAM;
        char portstr[10];
        snprintf(portstr, sizeof(portstr), "%d", (int) a_port);
        struct addrinfo* l_addrinfo;
        int l_gaierr;
        l_gaierr = getaddrinfo(a_host.c_str(), portstr, &l_hints, &l_addrinfo);
        if(l_gaierr != 0)
        {
                //NDBG_PRINT("Error getaddrinfo '%s': %s\n", a_host.c_str(), gai_strerror(l_gaierr));
                return STATUS_ERROR;
        }
        // Find the first IPv4 and IPv6 entries.
        struct addrinfo* l_addrinfo_v4 = NULL;
        struct addrinfo* l_addrinfo_v6 = NULL;
        for (struct addrinfo* i_addrinfo = l_addrinfo;
             i_addrinfo != (struct addrinfo*) 0;
             i_addrinfo = i_addrinfo->ai_next)
        {
                switch (i_addrinfo->ai_family)
                {
                case AF_INET:
                {
                        if(l_addrinfo_v4 == (struct addrinfo*) 0)
                        {
                                l_addrinfo_v4 = i_addrinfo;
                        }
                        break;
                }
                case AF_INET6:
                {
                        if(l_addrinfo_v6 == (struct addrinfo*) 0)
                        {
                                l_addrinfo_v6 = i_addrinfo;
                        }
                        break;
                }
                }
                if(l_addrinfo_v4 ||
                   l_addrinfo_v6)
                {
                        break;
                }
        }
        // If there's an IPv4 address, use that, otherwise try IPv6.
        if(l_addrinfo_v4 != NULL)
        {
                if(sizeof(ao_host_info.m_sa) < l_addrinfo_v4->ai_addrlen)
                {
                        //NDBG_PRINT("Error %s - sockaddr too small (%lu < %lu)\n",
                        //           a_host.c_str(),
                        //      (unsigned long) sizeof(ao_host_info.m_sa),
                        //      (unsigned long) l_addrinfo_v4->ai_addrlen);
                        return STATUS_ERROR;
                }
                ao_host_info.m_sock_family = l_addrinfo_v4->ai_family;
                ao_host_info.m_sock_type = l_addrinfo_v4->ai_socktype;
                ao_host_info.m_sock_protocol = l_addrinfo_v4->ai_protocol;
                ao_host_info.m_sa_len = l_addrinfo_v4->ai_addrlen;
                //NDBG_PRINT("memmove: addrlen: %d\n", l_addrinfo_v4->ai_addrlen);
                //mem_display((const uint8_t *)l_addrinfo_v4->ai_addr,
                //            l_addrinfo_v4->ai_addrlen,
                //            true);
                memmove(&(ao_host_info.m_sa),
                        l_addrinfo_v4->ai_addr,
                        l_addrinfo_v4->ai_addrlen);
                // Set the port
                ((sockaddr_in *)(&(ao_host_info.m_sa)))->sin_port = htons(a_port);
                freeaddrinfo(l_addrinfo);
        }
        else if(l_addrinfo_v6 != NULL)
        {
                if(sizeof(ao_host_info.m_sa) < l_addrinfo_v6->ai_addrlen)
                {
                        //NDBG_PRINT("Error %s - sockaddr too small (%lu < %lu)\n",
                        //           a_host.c_str(),
                        //      (unsigned long) sizeof(ao_host_info.m_sa),
                        //      (unsigned long) l_addrinfo_v6->ai_addrlen);
                        return STATUS_ERROR;
                }
                ao_host_info.m_sock_family = l_addrinfo_v6->ai_family;
                ao_host_info.m_sock_type = l_addrinfo_v6->ai_socktype;
                ao_host_info.m_sock_protocol = l_addrinfo_v6->ai_protocol;
                ao_host_info.m_sa_len = l_addrinfo_v6->ai_addrlen;
                //NDBG_PRINT("memmove: addrlen: %d\n", l_addrinfo_v6->ai_addrlen);
                //ns_hurl::mem_display((const uint8_t *)l_addrinfo_v6->ai_addr,
                //                     l_addrinfo_v6->ai_addrlen,
                //                     true);
                memmove(&ao_host_info.m_sa,
                        l_addrinfo_v6->ai_addr,
                        l_addrinfo_v6->ai_addrlen);
                // Set the port
                ((sockaddr_in6 *)(&(ao_host_info.m_sa)))->sin6_port = htons(a_port);
                freeaddrinfo(l_addrinfo);
        }
        else
        {
                //NDBG_PRINT("Error no valid address found for host %s\n", a_host.c_str());
                return STATUS_ERROR;
        }
        // Set to 60min -cuz getaddr-info stinks...
        ao_host_info.m_expires_s = get_time_s() + 3600;
        return STATUS_OK;
}
}
<|endoftext|>


<commit_before>// Version: $Id$
//
//

// Commentary:
//
//

// Change Log:
//
//

// Code:

// /////////////////////////////////////////////////////////////////
// dtkDistributedGraph implementation
// /////////////////////////////////////////////////////////////////

inline dtkDistributedGraph::dtkDistributedGraph(dtkDistributedWorker *worker) : dtkDistributedContainer(worker)
{
}

inline dtkDistributedGraph::dtkDistributedGraph(const qlonglong& vertex_count, dtkDistributedWorker *worker) : dtkDistributedContainer(vertex_count, worker)
{
    this->initialize();
}

inline dtkDistributedGraph::~dtkDistributedGraph(void)
{
}

inline qlonglong dtkDistributedGraph::vertexCount(void) const
{
    return this->size();
}

inline qlonglong dtkDistributedGraph::edgeCount(void) const
{
    return m_edge_count->at(this->wid());
}

inline void dtkDistributedGraph::initialize(void)
{
    qDebug() << "initialize graph with " << vertexCount() << "vertexes";

    m_vertices = new dtkDistributedArray<qlonglong>(vertexCount() + 1, this->worker());

    m_edge_count = new dtkDistributedArray<qlonglong>(m_comm->size(), this->worker());
    for (qint32 i = 0; i< m_comm->size(); i++) {
        if (i == this->wid()) {
            m_edge_count->setAt(i,0);
        }
    }

    m_mapper->setMapping(vertexCount(), m_comm->size());
}

inline void dtkDistributedGraph::build(void)
{
    this->m_comm->barrier();

    qlonglong edge_count = 0;
    for (qlonglong i = 0; i < m_comm->size(); ++i) {
        edge_count += m_edge_count->at(i);
    }

    dtkDistributedMapper *mapper = new dtkDistributedMapper;
    mapper->initMap(edge_count, m_comm->size());

    qlonglong offset = 0;
    for (qlonglong i = 0; i < m_comm->size(); ++i) {
        mapper->setMap(offset ,i);
        offset += m_edge_count->at(i);
    }

    m_edges = new dtkDistributedArray<qlonglong>(edge_count, this->worker(), mapper);

    EdgeMap::const_iterator it  = m_map.cbegin();
    EdgeMap::const_iterator end = m_map.cend();

    offset = mapper->startIndex(this->wid());
    qlonglong index = 0;
    for (; it != end; ++it) {
        m_vertices->setAt(it.key(), offset);
        offset += (*it).count();
        EdgeList::const_iterator nit  = (*it).begin();
        EdgeList::const_iterator nend = (*it).end();
        for(;nit != nend; ++nit) {
            m_edges->setLocalValue(index, *nit);
            ++index;
        }
    }

    this->m_comm->barrier();
    if (this->wid() == this->m_comm->size() - 1) {
        m_vertices->setAt(m_vertices->size() - 1, offset);
    }

    this->m_comm->barrier();
}

// read graph from file as described in
// http://people.sc.fsu.edu/~jburkardt/data/metis_graph/metis_graph.html

inline bool dtkDistributedGraph::read(const QString& filename)
{
    QFile file(filename);
    QTextStream in(&file);
    qlonglong edges_count = 0;

    if (this->wid() == 0) {

        if(filename.isEmpty() || (!file.exists())) {
            qWarning() << "input file is empty/does not exist" << filename << "Current dir is" << QDir::currentPath();
            return false;
        }
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return false;

        QStringList header = in.readLine().split(' ');
        m_size = header.first().toLongLong();
        if (m_size  == 0) {
            qWarning() << "Can't parse size of the graph" << filename;
            return false;
        }
        edges_count = header.at(1).toLongLong();
        if (edges_count  == 0) {
            qWarning() << "Can't parse the number of edges" << filename;
            return false;
        }

    }
    m_comm->broadcast(&m_size, 1, 0);
    m_comm->broadcast(&edges_count, 1, 0);

    this->initialize();
    m_comm->barrier();

    m_edges = new dtkDistributedArray<qlonglong>(2 * edges_count, this->worker());

    if (this->wid() == 0) {

        qlonglong index              = 0;
        qlonglong current_edge_count = 0;
        qlonglong current_owner      = 0;
        qlonglong current_vertice    = 0;

        QString line;
        QStringList edges;
        m_vertices->setAt(0, 0);

        while (!in.atEnd()) {
            line = in.readLine().trimmed();
            edges = line.split(' ');
            for (qlonglong i = 0; i < edges.size(); ++i) {
                m_edges->setAt(index, edges.at(i).toLongLong() -1);
                ++index;
                ++current_edge_count;
            }

            ++current_vertice;
            m_vertices->setAt(current_vertice, index);

            if (m_vertices->mapper()->owner(current_vertice) != current_owner) {
                m_edge_count->setAt(current_owner, current_edge_count);
                current_owner = m_vertices->mapper()->owner(current_vertice);
                current_edge_count = 0;
            }
        }
    }

    m_comm->barrier();

    qDebug() << "remap";
    dtkDistributedMapper *mapper = new dtkDistributedMapper;
    mapper->initMap(edges_count, m_comm->size());

    qlonglong offset = 0;
    for (qlonglong i = 0; i < m_comm->size(); ++i) {
        mapper->setMap(offset ,i);
        offset += m_edge_count->at(i);
    }
    m_edges->remap(mapper);
    qDebug() << "remap done";

    return true;
}

inline void dtkDistributedGraph::appendEdge(qlonglong from, qlonglong to)
{
    qint32 from_owner = static_cast<qint32>(m_mapper->owner(from));
    qint32 to_owner = static_cast<qint32>(m_mapper->owner(to));
    qint32 wid = this->wid();
    if ((wid != from_owner) && (wid != to_owner))
        return;

    qlonglong edge_counter = m_edge_count->at(this->wid());

    if (wid == from_owner) {
        m_map[from].append(to);
        ++edge_counter;
    }
    if (wid == to_owner) {
        m_map[to].append(from);
        ++edge_counter;
    }
    m_edge_count->setAt(wid, edge_counter);
}

inline qlonglong dtkDistributedGraph::edgeCount(qlonglong vertex_id) const
{
    qlonglong start = m_vertices->at(vertex_id);
    return (m_vertices->at(vertex_id + 1) - start);
}

inline dtkDistributedGraph::Neighbours dtkDistributedGraph::neighbours(const qlonglong& vertex_id) const
{
    qlonglong n_start = m_vertices->at(vertex_id);
    qlonglong size = m_vertices->at(vertex_id + 1) - n_start;

    return Neighbours(m_edges, n_start, size);
}

//
// dtkDistributedGraph.tpp ends here
<commit_msg>fix remapper size<commit_after>// Version: $Id$
//
//

// Commentary:
//
//

// Change Log:
//
//

// Code:

// /////////////////////////////////////////////////////////////////
// dtkDistributedGraph implementation
// /////////////////////////////////////////////////////////////////

inline dtkDistributedGraph::dtkDistributedGraph(dtkDistributedWorker *worker) : dtkDistributedContainer(worker)
{
}

inline dtkDistributedGraph::dtkDistributedGraph(const qlonglong& vertex_count, dtkDistributedWorker *worker) : dtkDistributedContainer(vertex_count, worker)
{
    this->initialize();
}

inline dtkDistributedGraph::~dtkDistributedGraph(void)
{
}

inline qlonglong dtkDistributedGraph::vertexCount(void) const
{
    return this->size();
}

inline qlonglong dtkDistributedGraph::edgeCount(void) const
{
    return m_edge_count->at(this->wid());
}

inline void dtkDistributedGraph::initialize(void)
{
    qDebug() << "initialize graph with " << vertexCount() << "vertexes";

    m_vertices = new dtkDistributedArray<qlonglong>(vertexCount() + 1, this->worker());

    m_edge_count = new dtkDistributedArray<qlonglong>(m_comm->size(), this->worker());
    for (qint32 i = 0; i< m_comm->size(); i++) {
        if (i == this->wid()) {
            m_edge_count->setAt(i,0);
        }
    }

    m_mapper->setMapping(vertexCount(), m_comm->size());
}

inline void dtkDistributedGraph::build(void)
{
    this->m_comm->barrier();

    qlonglong edge_count = 0;
    for (qlonglong i = 0; i < m_comm->size(); ++i) {
        edge_count += m_edge_count->at(i);
    }

    dtkDistributedMapper *mapper = new dtkDistributedMapper;
    mapper->initMap(edge_count, m_comm->size());

    qlonglong offset = 0;
    for (qlonglong i = 0; i < m_comm->size(); ++i) {
        mapper->setMap(offset ,i);
        offset += m_edge_count->at(i);
    }

    m_edges = new dtkDistributedArray<qlonglong>(edge_count, this->worker(), mapper);

    EdgeMap::const_iterator it  = m_map.cbegin();
    EdgeMap::const_iterator end = m_map.cend();

    offset = mapper->startIndex(this->wid());
    qlonglong index = 0;
    for (; it != end; ++it) {
        m_vertices->setAt(it.key(), offset);
        offset += (*it).count();
        EdgeList::const_iterator nit  = (*it).begin();
        EdgeList::const_iterator nend = (*it).end();
        for(;nit != nend; ++nit) {
            m_edges->setLocalValue(index, *nit);
            ++index;
        }
    }

    this->m_comm->barrier();
    if (this->wid() == this->m_comm->size() - 1) {
        m_vertices->setAt(m_vertices->size() - 1, offset);
    }

    this->m_comm->barrier();
}

// read graph from file as described in
// http://people.sc.fsu.edu/~jburkardt/data/metis_graph/metis_graph.html

inline bool dtkDistributedGraph::read(const QString& filename)
{
    QFile file(filename);
    QTextStream in(&file);
    qlonglong edges_count = 0;

    if (this->wid() == 0) {

        if(filename.isEmpty() || (!file.exists())) {
            qWarning() << "input file is empty/does not exist" << filename << "Current dir is" << QDir::currentPath();
            return false;
        }
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return false;

        QStringList header = in.readLine().split(' ');
        m_size = header.first().toLongLong();
        if (m_size  == 0) {
            qWarning() << "Can't parse size of the graph" << filename;
            return false;
        }
        edges_count = header.at(1).toLongLong();
        if (edges_count  == 0) {
            qWarning() << "Can't parse the number of edges" << filename;
            return false;
        }

    }
    m_comm->broadcast(&m_size, 1, 0);
    m_comm->broadcast(&edges_count, 1, 0);

    this->initialize();
    m_comm->barrier();

    m_edges = new dtkDistributedArray<qlonglong>(2 * edges_count, this->worker());

    if (this->wid() == 0) {

        qlonglong index              = 0;
        qlonglong current_edge_count = 0;
        qlonglong current_owner      = 0;
        qlonglong current_vertice    = 0;

        QString line;
        QStringList edges;
        m_vertices->setAt(0, 0);

        while (!in.atEnd()) {
            line = in.readLine().trimmed();
            edges = line.split(' ');
            for (qlonglong i = 0; i < edges.size(); ++i) {
                m_edges->setAt(index, edges.at(i).toLongLong() -1);
                ++index;
                ++current_edge_count;
            }

            ++current_vertice;
            m_vertices->setAt(current_vertice, index);

            if (m_vertices->mapper()->owner(current_vertice) != current_owner) {
                m_edge_count->setAt(current_owner, current_edge_count);
                current_owner = m_vertices->mapper()->owner(current_vertice);
                current_edge_count = 0;
            }
        }
    }

    m_comm->barrier();

    qDebug() << "remap";
    dtkDistributedMapper *mapper = new dtkDistributedMapper;
    mapper->initMap(2 * edges_count, m_comm->size());

    qlonglong offset = 0;
    for (qlonglong i = 0; i < m_comm->size(); ++i) {
        mapper->setMap(offset ,i);
        offset += m_edge_count->at(i);
    }
    m_edges->remap(mapper);
    qDebug() << "remap done";

    return true;
}

inline void dtkDistributedGraph::appendEdge(qlonglong from, qlonglong to)
{
    qint32 from_owner = static_cast<qint32>(m_mapper->owner(from));
    qint32 to_owner = static_cast<qint32>(m_mapper->owner(to));
    qint32 wid = this->wid();
    if ((wid != from_owner) && (wid != to_owner))
        return;

    qlonglong edge_counter = m_edge_count->at(this->wid());

    if (wid == from_owner) {
        m_map[from].append(to);
        ++edge_counter;
    }
    if (wid == to_owner) {
        m_map[to].append(from);
        ++edge_counter;
    }
    m_edge_count->setAt(wid, edge_counter);
}

inline qlonglong dtkDistributedGraph::edgeCount(qlonglong vertex_id) const
{
    qlonglong start = m_vertices->at(vertex_id);
    return (m_vertices->at(vertex_id + 1) - start);
}

inline dtkDistributedGraph::Neighbours dtkDistributedGraph::neighbours(const qlonglong& vertex_id) const
{
    qlonglong n_start = m_vertices->at(vertex_id);
    qlonglong size = m_vertices->at(vertex_id + 1) - n_start;

    return Neighbours(m_edges, n_start, size);
}

//
// dtkDistributedGraph.tpp ends here
<|endoftext|>


<commit_before>#include "Reseedable.h"
#include "MakeReseedable.h"
#include "ModuleGroup.h"
#include "Exp.h"

double Reseedable::getValue(double x, double y, double z)
{
    return module->GetValue(x, y, z);
}

Reseedable Reseedable::abs()
{
    std::shared_ptr<noise::module::Abs> abs_p = std::make_shared<noise::module::Abs>();
    abs_p->SetSourceModule(0, *module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(abs_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::clamp(double lower, double upper)
{
    std::shared_ptr<noise::module::Clamp> clamp_p = std::make_shared<noise::module::Clamp>();
    clamp_p->SetSourceModule(0, *module);
    clamp_p->SetBounds(lower, upper);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(clamp_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::exp(double base)
{
    std::shared_ptr<Exp> exponent_p = std::make_shared<Exp>();
    exponent_p->SetSourceModule(0, *module);
    exponent_p->SetBase(base);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(exponent_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::invert()
{
    std::shared_ptr<noise::module::Invert> invert_p = std::make_shared<noise::module::Invert>();
    invert_p->SetSourceModule(0, *module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(invert_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::scaleBias(double scale, double bias)
{
    std::shared_ptr<noise::module::ScaleBias> scale_bias_p = std::make_shared<noise::module::ScaleBias>();
    scale_bias_p->SetSourceModule(0, *module);
    scale_bias_p->SetScale(scale);
    scale_bias_p->SetBias(bias);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(scale_bias_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::operator+(Reseedable & other)
{
    std::shared_ptr<noise::module::Add> add_p = std::make_shared<noise::module::Add>();
    add_p->SetSourceModule(0, *module);
    add_p->SetSourceModule(1, *other.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source0", *this);
    mg->insert("source1", other);
    mg->insert("output", makeReseedable(add_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::operator+(double bias)
{
    std::shared_ptr<noise::module::ScaleBias> scale_bias_p = std::make_shared<noise::module::ScaleBias>();
    scale_bias_p->SetSourceModule(0, *module);
    scale_bias_p->SetScale(1.);
    scale_bias_p->SetBias(bias);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(scale_bias_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::operator-(Reseedable & other)
{
    return operator+(other.invert());
}

Reseedable Reseedable::operator-(double bias)
{
    return operator+(-bias);
}

Reseedable Reseedable::operator-()
{
    return invert();
}

Reseedable Reseedable::max(Reseedable & other)
{
    std::shared_ptr<noise::module::Max> max_p = std::make_shared<noise::module::Max>();
    max_p->SetSourceModule(0, *module);
    max_p->SetSourceModule(1, *other.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source0", *this);
    mg->insert("source1", other);
    mg->insert("output", makeReseedable(max_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::max(double other)
{
    auto c = std::make_shared<noise::module::Const>();
    c->SetConstValue(other);
    return max(makeReseedable(c));
}

Reseedable Reseedable::min(Reseedable & other)
{
    std::shared_ptr<noise::module::Min> min_p = std::make_shared<noise::module::Min>();
    min_p->SetSourceModule(0, *module);
    min_p->SetSourceModule(1, *other.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source0", *this);
    mg->insert("source1", other);
    mg->insert("output", makeReseedable(min_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::min(double other)
{
    auto c = std::make_shared<noise::module::Const>();
    c->SetConstValue(other);
    return min(makeReseedable(c));
}

Reseedable Reseedable::operator*(Reseedable & other)
{
    std::shared_ptr<noise::module::Multiply> multiply_p = std::make_shared<noise::module::Multiply>();
    multiply_p->SetSourceModule(0, *module);
    multiply_p->SetSourceModule(1, *other.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source0", *this);
    mg->insert("source1", other);
    mg->insert("output", makeReseedable(multiply_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::operator*(double scale)
{
    std::shared_ptr<noise::module::ScaleBias> scale_bias_p = std::make_shared<noise::module::ScaleBias>();
    scale_bias_p->SetSourceModule(0, *module);
    scale_bias_p->SetScale(scale);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(scale_bias_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::pow(Reseedable & exponent)
{
    std::shared_ptr<noise::module::Power> power_p = std::make_shared<noise::module::Power>();
    power_p->SetSourceModule(0, *module);
    power_p->SetSourceModule(1, *exponent.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("base", *this);
    mg->insert("exponent", exponent);
    mg->insert("output", makeReseedable(power_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::pow(double exponent)
{
    std::shared_ptr<Power> exponent_p = std::make_shared<Power>();
    exponent_p->SetSourceModule(0, *module);
    exponent_p->SetExponent(exponent);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(exponent_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::blend(Reseedable& source_a, Reseedable& source_b)
{
    std::shared_ptr<noise::module::Blend> blend_p = std::make_shared<noise::module::Blend>();
    blend_p->SetSourceModule(0, *source_a.module);
    blend_p->SetSourceModule(1, *source_b.module);
    blend_p->SetControlModule(*module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("control", *this);
    mg->insert("source0", source_a);
    mg->insert("source1", source_b);
    mg->insert("output", makeReseedable(blend_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::select(Reseedable& source_a, Reseedable& source_b)
{
    std::shared_ptr<noise::module::Select> select_p = std::make_shared<noise::module::Select>();
    select_p->SetSourceModule(0, *source_a.module);
    select_p->SetSourceModule(1, *source_b.module);
    select_p->SetControlModule(*module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("control", *this);
    mg->insert("source0", source_a);
    mg->insert("source1", source_b);
    mg->insert("output", makeReseedable(select_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::rotatePoint(double x_angle, double y_angle, double z_angle)
{
    std::shared_ptr<noise::module::RotatePoint> rotate_point_p = std::make_shared<noise::module::RotatePoint>();
    rotate_point_p->SetSourceModule(0, *module);
    rotate_point_p->SetXAngle(x_angle);
    rotate_point_p->SetYAngle(y_angle);
    rotate_point_p->SetZAngle(z_angle);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(rotate_point_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::scalePoint(double x_scale, double y_scale, double z_scale)
{
    std::shared_ptr<noise::module::ScalePoint> scale_point_p = std::make_shared<noise::module::ScalePoint>();
    scale_point_p->SetSourceModule(0, *module);
    scale_point_p->SetXScale(x_scale);
    scale_point_p->SetYScale(y_scale);
    scale_point_p->SetZScale(z_scale);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(scale_point_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::translatePoint(double x_displace, double y_displace, double z_displace)
{
    std::shared_ptr<noise::module::TranslatePoint> translate_point_p = std::make_shared<noise::module::TranslatePoint>();
    translate_point_p->SetSourceModule(0, *module);
    translate_point_p->SetXTranslation(x_displace);
    translate_point_p->SetYTranslation(y_displace);
    translate_point_p->SetZTranslation(z_displace);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(translate_point_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::turbulence(double frequency, double power, int roughness, int seed)
{
    auto turbulence_p = std::make_shared<noise::module::Turbulence>();
    turbulence_p->SetFrequency(frequency);
    turbulence_p->SetPower(power);
    turbulence_p->SetRoughness(roughness);
    turbulence_p->SetSeed(seed);
    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(turbulence_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::displace(Reseedable & x_displace, Reseedable & y_displace, Reseedable & z_displace)
{
    throw;
    return Reseedable();
}
<commit_msg>Fix turbulence and implement displace<commit_after>#include "Reseedable.h"
#include "MakeReseedable.h"
#include "ModuleGroup.h"
#include "Exp.h"

double Reseedable::getValue(double x, double y, double z)
{
    return module->GetValue(x, y, z);
}

Reseedable Reseedable::abs()
{
    std::shared_ptr<noise::module::Abs> abs_p = std::make_shared<noise::module::Abs>();
    abs_p->SetSourceModule(0, *module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(abs_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::clamp(double lower, double upper)
{
    std::shared_ptr<noise::module::Clamp> clamp_p = std::make_shared<noise::module::Clamp>();
    clamp_p->SetSourceModule(0, *module);
    clamp_p->SetBounds(lower, upper);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(clamp_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::exp(double base)
{
    std::shared_ptr<Exp> exponent_p = std::make_shared<Exp>();
    exponent_p->SetSourceModule(0, *module);
    exponent_p->SetBase(base);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(exponent_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::invert()
{
    std::shared_ptr<noise::module::Invert> invert_p = std::make_shared<noise::module::Invert>();
    invert_p->SetSourceModule(0, *module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(invert_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::scaleBias(double scale, double bias)
{
    std::shared_ptr<noise::module::ScaleBias> scale_bias_p = std::make_shared<noise::module::ScaleBias>();
    scale_bias_p->SetSourceModule(0, *module);
    scale_bias_p->SetScale(scale);
    scale_bias_p->SetBias(bias);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(scale_bias_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::operator+(Reseedable & other)
{
    std::shared_ptr<noise::module::Add> add_p = std::make_shared<noise::module::Add>();
    add_p->SetSourceModule(0, *module);
    add_p->SetSourceModule(1, *other.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source0", *this);
    mg->insert("source1", other);
    mg->insert("output", makeReseedable(add_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::operator+(double bias)
{
    std::shared_ptr<noise::module::ScaleBias> scale_bias_p = std::make_shared<noise::module::ScaleBias>();
    scale_bias_p->SetSourceModule(0, *module);
    scale_bias_p->SetScale(1.);
    scale_bias_p->SetBias(bias);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(scale_bias_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::operator-(Reseedable & other)
{
    return operator+(other.invert());
}

Reseedable Reseedable::operator-(double bias)
{
    return operator+(-bias);
}

Reseedable Reseedable::operator-()
{
    return invert();
}

Reseedable Reseedable::max(Reseedable & other)
{
    std::shared_ptr<noise::module::Max> max_p = std::make_shared<noise::module::Max>();
    max_p->SetSourceModule(0, *module);
    max_p->SetSourceModule(1, *other.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source0", *this);
    mg->insert("source1", other);
    mg->insert("output", makeReseedable(max_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::max(double other)
{
    auto c = std::make_shared<noise::module::Const>();
    c->SetConstValue(other);
    return max(makeReseedable(c));
}

Reseedable Reseedable::min(Reseedable & other)
{
    std::shared_ptr<noise::module::Min> min_p = std::make_shared<noise::module::Min>();
    min_p->SetSourceModule(0, *module);
    min_p->SetSourceModule(1, *other.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source0", *this);
    mg->insert("source1", other);
    mg->insert("output", makeReseedable(min_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::min(double other)
{
    auto c = std::make_shared<noise::module::Const>();
    c->SetConstValue(other);
    return min(makeReseedable(c));
}

Reseedable Reseedable::operator*(Reseedable & other)
{
    std::shared_ptr<noise::module::Multiply> multiply_p = std::make_shared<noise::module::Multiply>();
    multiply_p->SetSourceModule(0, *module);
    multiply_p->SetSourceModule(1, *other.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source0", *this);
    mg->insert("source1", other);
    mg->insert("output", makeReseedable(multiply_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::operator*(double scale)
{
    std::shared_ptr<noise::module::ScaleBias> scale_bias_p = std::make_shared<noise::module::ScaleBias>();
    scale_bias_p->SetSourceModule(0, *module);
    scale_bias_p->SetScale(scale);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(scale_bias_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::pow(Reseedable & exponent)
{
    std::shared_ptr<noise::module::Power> power_p = std::make_shared<noise::module::Power>();
    power_p->SetSourceModule(0, *module);
    power_p->SetSourceModule(1, *exponent.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("base", *this);
    mg->insert("exponent", exponent);
    mg->insert("output", makeReseedable(power_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::pow(double exponent)
{
    std::shared_ptr<Power> exponent_p = std::make_shared<Power>();
    exponent_p->SetSourceModule(0, *module);
    exponent_p->SetExponent(exponent);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(exponent_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::blend(Reseedable& source_a, Reseedable& source_b)
{
    std::shared_ptr<noise::module::Blend> blend_p = std::make_shared<noise::module::Blend>();
    blend_p->SetSourceModule(0, *source_a.module);
    blend_p->SetSourceModule(1, *source_b.module);
    blend_p->SetControlModule(*module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("control", *this);
    mg->insert("source0", source_a);
    mg->insert("source1", source_b);
    mg->insert("output", makeReseedable(blend_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::select(Reseedable& source_a, Reseedable& source_b)
{
    std::shared_ptr<noise::module::Select> select_p = std::make_shared<noise::module::Select>();
    select_p->SetSourceModule(0, *source_a.module);
    select_p->SetSourceModule(1, *source_b.module);
    select_p->SetControlModule(*module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("control", *this);
    mg->insert("source0", source_a);
    mg->insert("source1", source_b);
    mg->insert("output", makeReseedable(select_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::rotatePoint(double x_angle, double y_angle, double z_angle)
{
    std::shared_ptr<noise::module::RotatePoint> rotate_point_p = std::make_shared<noise::module::RotatePoint>();
    rotate_point_p->SetSourceModule(0, *module);
    rotate_point_p->SetXAngle(x_angle);
    rotate_point_p->SetYAngle(y_angle);
    rotate_point_p->SetZAngle(z_angle);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(rotate_point_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::scalePoint(double x_scale, double y_scale, double z_scale)
{
    std::shared_ptr<noise::module::ScalePoint> scale_point_p = std::make_shared<noise::module::ScalePoint>();
    scale_point_p->SetSourceModule(0, *module);
    scale_point_p->SetXScale(x_scale);
    scale_point_p->SetYScale(y_scale);
    scale_point_p->SetZScale(z_scale);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(scale_point_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::translatePoint(double x_displace, double y_displace, double z_displace)
{
    std::shared_ptr<noise::module::TranslatePoint> translate_point_p = std::make_shared<noise::module::TranslatePoint>();
    translate_point_p->SetSourceModule(0, *module);
    translate_point_p->SetXTranslation(x_displace);
    translate_point_p->SetYTranslation(y_displace);
    translate_point_p->SetZTranslation(z_displace);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(translate_point_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::turbulence(double frequency, double power, int roughness, int seed)
{
    auto turbulence_p = std::make_shared<noise::module::Turbulence>();
    turbulence_p->SetFrequency(frequency);
    turbulence_p->SetPower(power);
    turbulence_p->SetRoughness(roughness);
    turbulence_p->SetSeed(seed);
    turbulence_p->SetSourceModule(0, *module);
    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("output", makeReseedable(turbulence_p));
    return makeReseedable(mg);
}

Reseedable Reseedable::displace(Reseedable & x_displace, Reseedable & y_displace, Reseedable & z_displace)
{
    auto displace_p = std::make_shared<noise::module::Displace>();
    displace_p->SetSourceModule(0, *module);
    displace_p->SetXDisplaceModule(*x_displace.module);
    displace_p->SetYDisplaceModule(*y_displace.module);
    displace_p->SetZDisplaceModule(*z_displace.module);

    std::shared_ptr<ModuleGroup> mg = std::make_shared<ModuleGroup>();
    mg->insert("source", *this);
    mg->insert("displaceX", x_displace);
    mg->insert("displaceY", y_displace);
    mg->insert("displaceZ", z_displace);
    mg->insert("output", makeReseedable(displace_p));
    return makeReseedable(mg);
}
<|endoftext|>


<commit_before>#include "common/LinkParser.hpp"

#include "debug/Log.hpp"

#include <QFile>
#include <QRegularExpression>
#include <QString>
#include <QTextStream>

#include <mutex>

namespace chatterino {

namespace {

std::once_flag regexInitializedFlag;
QRegularExpression *linkRegex = nullptr;

void initializeRegularExpressions()
{
    std::call_once(regexInitializedFlag, [] {
        QFile tldFile(":/tlds.txt");
        tldFile.open(QFile::ReadOnly);
        QTextStream t1(&tldFile);
        t1.setCodec("UTF-8");
        QString tldData = t1.readAll();
        tldData.replace("\n", "|");
        const QString urlRegExp =
            "^"
            // protocol identifier
            "(?:(?:https?|ftps?)://)?"
            // user:pass authentication
            "(?:\\S+(?::\\S*)?@)?"
            "(?:"
            // IP address dotted notation octets
            // excludes loopback network 0.0.0.0
            // excludes reserved space >= 224.0.0.0
            // excludes network & broacast addresses
            // (first & last IP address of each class)
            "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])"
            "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}"
            "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))"
            "|"
            // host name
            "(?:(?:[_a-z\\x{00a1}-\\x{ffff}0-9]-*)*[a-z\\x{00a1}-\\x{ffff}0-9]+)"
            // domain name
            "(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}0-9]-*)*[a-z\\x{00a1}-\\x{ffff}0-9]+)*"
            // TLD identifier
            //"(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}]{2,}))"
            "(?:[\\.](?:" +
            tldData +
            "))"
            "\\.?"
            ")"
            // port number
            "(?::\\d{2,5})?"
            // resource path
            "(?:[/?#]\\S*)?"
            "$";
        linkRegex = new QRegularExpression(urlRegExp, QRegularExpression::CaseInsensitiveOption);

        Log("fully initialized");
    });

    Log("call_once returned");
}

}  // namespace

LinkParser::LinkParser(const QString &unparsedString)
{
    initializeRegularExpressions();

    this->match_ = linkRegex->match(unparsedString);
}

}  // namespace chatterino
<commit_msg>Reduce complexity of regular expression initialization<commit_after>#include "common/LinkParser.hpp"

#include <QFile>
#include <QRegularExpression>
#include <QString>
#include <QTextStream>

namespace chatterino {

LinkParser::LinkParser(const QString &unparsedString)
{
    static QRegularExpression linkRegex = [] {
        QFile tldFile(":/tlds.txt");
        tldFile.open(QFile::ReadOnly);

        QTextStream t1(&tldFile);
        t1.setCodec("UTF-8");

        // Read the TLDs in and replace the newlines with pipes
        QString tldData = t1.readAll().replace("\n", "|");

        const QString urlRegExp =
            "^"
            // protocol identifier
            "(?:(?:https?|ftps?)://)?"
            // user:pass authentication
            "(?:\\S+(?::\\S*)?@)?"
            "(?:"
            // IP address dotted notation octets
            // excludes loopback network 0.0.0.0
            // excludes reserved space >= 224.0.0.0
            // excludes network & broacast addresses
            // (first & last IP address of each class)
            "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])"
            "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}"
            "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))"
            "|"
            // host name
            "(?:(?:[_a-z\\x{00a1}-\\x{ffff}0-9]-*)*[a-z\\x{00a1}-\\x{ffff}0-9]+)"
            // domain name
            "(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}0-9]-*)*[a-z\\x{00a1}-\\x{ffff}0-9]+)*"
            // TLD identifier
            //"(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}]{2,}))"
            "(?:[\\.](?:" +
            tldData +
            "))"
            "\\.?"
            ")"
            // port number
            "(?::\\d{2,5})?"
            // resource path
            "(?:[/?#]\\S*)?"
            "$";

        return QRegularExpression(urlRegExp, QRegularExpression::CaseInsensitiveOption);
    }();

    this->match_ = linkRegex.match(unparsedString);
}

}  // namespace chatterino
<|endoftext|>


<commit_before>/* Gobby - GTK-based collaborative text editor
 * Copyright (C) 2008-2014 Armin Burgmeier <armin@arbur.net>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "core/statusbar.hpp"
#include "util/gtk-compat.hpp"
#include "util/i18n.hpp"

#include <glibmm/main.h>
#include <gtkmm/frame.h>
#include <gtkmm/stock.h>

namespace
{
	Gtk::StockID
	message_type_to_stock_id(Gobby::StatusBar::MessageType type)
	{
		switch(type)
		{
		case Gobby::StatusBar::INFO:
			return Gtk::Stock::DIALOG_INFO;
		case Gobby::StatusBar::ERROR:
			return Gtk::Stock::DIALOG_ERROR;
		default:
			g_assert_not_reached();
		}
	}

	void dispose_dialog(Gtk::MessageDialog* dialog)
	{
		delete dialog;
	}
}

class Gobby::StatusBar::Message
{
public:
	Message(Gtk::Widget* widget,
	        const Glib::ustring& simple,
	        const Glib::ustring& detail,
		sigc::connection timeout_conn = sigc::connection()):
		m_widget(widget), m_timeout_conn(timeout_conn),
		m_simple_desc(simple), m_detail_desc(detail)
	{
	}

	~Message()
	{
		m_timeout_conn.disconnect();
	}

	void show_dialog() const
	{
		Gtk::MessageDialog* dialog = new Gtk::MessageDialog(
			m_simple_desc,
			false,
			Gtk::MESSAGE_ERROR,
			Gtk::BUTTONS_NONE,
			false);

		dialog->add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);

		dialog->set_secondary_text(m_detail_desc, true);
		dialog->signal_response().connect(
			sigc::hide(
				sigc::bind(
					sigc::ptr_fun(dispose_dialog),
					dialog)));
		dialog->show();
	}

	bool is_error() { return !m_detail_desc.empty(); }

	Gtk::Widget* widget() const { return m_widget; }

protected:
	Gtk::Widget* m_widget;
	sigc::connection m_timeout_conn;
	Glib::ustring m_simple_desc;
	Glib::ustring m_detail_desc;
};

Gobby::StatusBar::StatusBar(Gtk::Window& window,
                            const Folder& folder,
                            const Preferences& preferences):
	Gtk::HBox(false, 2), m_folder(folder), m_preferences(preferences),
	m_visible_messages(0), m_current_view(NULL), m_position_context_id(0)
{
	pack_end(m_bar_position, Gtk::PACK_SHRINK);
	m_bar_position.set_size_request(200, -1);
	m_bar_position.show();

	window.signal_window_state_event().connect(
		sigc::mem_fun(*this, &StatusBar::on_window_state_event));

	m_folder.signal_document_removed().connect(
		sigc::mem_fun(*this, &StatusBar::on_document_removed));
	m_folder.signal_document_changed().connect(
		sigc::mem_fun(*this, &StatusBar::on_document_changed));
	m_preferences.appearance.show_statusbar.signal_changed().connect(
		sigc::mem_fun(*this, &StatusBar::on_view_changed));

	// Initial update
	on_document_changed(m_folder.get_current_document());
	on_view_changed();
}

Gobby::StatusBar::~StatusBar()
{
	on_document_changed(NULL);
}

Gobby::StatusBar::MessageHandle
Gobby::StatusBar::add_message(Gobby::StatusBar::MessageType type,
                              const Glib::ustring& message,
                              const Glib::ustring& dialog_message,
                              unsigned int timeout)
{
	if(m_visible_messages >= 12)
	{
		for(MessageHandle iter = m_list.begin();
		    iter != m_list.end();
		    ++iter)
		{
			if(*iter)
			{
				if((*iter)->is_error())
					remove_message(iter);
				else
					// only hide message because whoever
					// installed it is expecting to be
					// able to call remove_message on it
					hide_message(iter);
				break;
			}
		}
	}

	Gtk::HBox* bar = Gtk::manage(new Gtk::HBox);

	Gtk::Image* image = Gtk::manage(new Gtk::Image(
		message_type_to_stock_id(type), Gtk::ICON_SIZE_MENU));
	bar->pack_start(*image, Gtk::PACK_SHRINK);
	image->show();

	Gtk::Label* label = Gtk::manage(
		new Gtk::Label(message, GtkCompat::ALIGN_LEFT));
	label->set_ellipsize(Pango::ELLIPSIZE_END);
	bar->pack_start(*label, Gtk::PACK_EXPAND_WIDGET);
	label->show();

	GtkShadowType shadow_type;
	gtk_widget_style_get(GTK_WIDGET(m_bar_position.gobj()),
	                     "shadow-type", &shadow_type, NULL);
	Gtk::Frame* frame = Gtk::manage(new Gtk::Frame);

	m_list.push_back(0);
	Gobby::StatusBar::MessageHandle iter(--m_list.end());
	sigc::connection timeout_conn;
	if(timeout)
	{
		timeout_conn = Glib::signal_timeout().connect_seconds(
			sigc::bind(
				sigc::bind_return(
					sigc::mem_fun(
						*this,
						&StatusBar::remove_message),
					false),
				iter),
			timeout);
	}
	*iter = new Message(frame, message, dialog_message, timeout_conn);
	++m_visible_messages;

	if(dialog_message.empty())
	{
		frame->add(*bar);
	}
	else
	{
		Gtk::EventBox *eventbox = Gtk::manage(new Gtk::EventBox);
		frame->add(*eventbox);
		eventbox->add(*bar);
		eventbox->signal_button_press_event().connect(
			sigc::bind_return(sigc::bind(
				sigc::mem_fun(
					*this,
					&StatusBar::on_message_clicked),
				iter), false));

		eventbox->show();
	}

	frame->set_shadow_type(static_cast<Gtk::ShadowType>(shadow_type));
	bar->show();

	pack_start(*frame, Gtk::PACK_EXPAND_WIDGET);
	reorder_child(*frame, 0);

	frame->show();

	return iter;
}

Gobby::StatusBar::MessageHandle
Gobby::StatusBar::add_info_message(const Glib::ustring& message,
                                   unsigned int timeout)
{
	MessageHandle handle =
		Gobby::StatusBar::add_message(INFO, message, "", timeout);
	// Caller is not allowed to hold on to handles to messages that we are
	// going to delete anyway.
	if(timeout)
		return invalid_handle();
	else
		return handle;
}

void
Gobby::StatusBar::add_error_message(const Glib::ustring& brief_desc,
                                    const Glib::ustring& detailed_desc,
                                    unsigned int timeout)
{
	Gobby::StatusBar::add_message(ERROR,
	                              brief_desc,
	                              detailed_desc,
	                              timeout);
}

void Gobby::StatusBar::remove_message(const MessageHandle& handle)
{
	hide_message(handle);
	m_list.erase(handle);
}

void Gobby::StatusBar::hide_message(const MessageHandle& handle)
{
	if(*handle != 0)
	{
		g_assert(m_visible_messages > 0);
		--m_visible_messages;
		remove(*(*handle)->widget());
		delete *handle;
		*handle = 0;
	}
}

Gobby::StatusBar::MessageHandle Gobby::StatusBar::invalid_handle()
{
	return m_list.end();
}

void Gobby::StatusBar::on_message_clicked(GdkEventButton* button,
                                          const MessageHandle& handle)
{
	if(button->button == 1)
		(*handle)->show_dialog();

	remove_message(handle);
}

void Gobby::StatusBar::on_document_removed(SessionView& view)
{
	if(m_current_view == &view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		g_signal_handler_disconnect(buffer, m_mark_set_handler);
		g_signal_handler_disconnect(buffer, m_changed_handler);
		g_signal_handler_disconnect(m_current_view->get_text_view(),
		                            m_toverwrite_handler);

		m_current_view = NULL;
	}
}

void Gobby::StatusBar::on_document_changed(SessionView* view)
{
	if(m_current_view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		g_signal_handler_disconnect(buffer, m_mark_set_handler);
		g_signal_handler_disconnect(buffer, m_changed_handler);
		g_signal_handler_disconnect(m_current_view->get_text_view(),
		                            m_toverwrite_handler);
	}

	m_current_view = dynamic_cast<TextSessionView*>(view);

	if(m_current_view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		m_mark_set_handler = g_signal_connect_after(
			G_OBJECT(buffer), "mark-set",
			G_CALLBACK(on_mark_set_static), this);

		m_changed_handler = g_signal_connect_after(
			G_OBJECT(buffer), "changed",
			G_CALLBACK(on_changed_static), this);

		m_toverwrite_handler = g_signal_connect_after(
			G_OBJECT(m_current_view->get_text_view()),
			"notify::overwrite",
			G_CALLBACK(on_toggled_overwrite_static), this);
	}

	// Initial update
	update_pos_display();
}

void Gobby::StatusBar::on_view_changed()
{
	if(m_preferences.appearance.show_statusbar) show();
	else hide();
}

void Gobby::StatusBar::on_mark_set(GtkTextMark* mark)
{
	GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
		m_current_view->get_text_buffer());

	if(mark == gtk_text_buffer_get_insert(buffer))
		update_pos_display();
}

void Gobby::StatusBar::on_toggled_overwrite()
{
	update_pos_display();
}

void Gobby::StatusBar::on_changed()
{
	update_pos_display();
}

bool Gobby::StatusBar::on_window_state_event(GdkEventWindowState* event)
{
	// In GTK+ 3 the resize grip is handled by the Window,
	// not the status bar
#ifndef USE_GTKMM3
	if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
		m_bar_position.set_has_resize_grip(false);
	else
		m_bar_position.set_has_resize_grip(true);
#endif

	return true;
}

void Gobby::StatusBar::update_pos_display()
{
	if(m_position_context_id)
		m_bar_position.remove_message(m_position_context_id);

	if(m_current_view != NULL)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());
		GtkTextIter iter;

		// TODO: Use TextSessionView::get_cursor_position()?
		gtk_text_buffer_get_iter_at_mark(
			buffer, &iter, gtk_text_buffer_get_insert(buffer));

		gint offset = gtk_text_iter_get_line_offset(&iter);

		unsigned int column = 0;
		const unsigned int tab_width = m_preferences.editor.tab_width;
		for(gtk_text_iter_set_line_offset(&iter, 0);
		    gtk_text_iter_get_line_offset(&iter) < offset;
		    gtk_text_iter_forward_char(&iter))
		{
			if(gtk_text_iter_get_char(&iter) == '\t')
				column += (tab_width - column % tab_width);
			else
				++ column;
		}

		// TODO: We might want to have a separate widget for the
		// OVR/INS display.
		m_position_context_id = m_bar_position.push(
			Glib::ustring::compose(
				_("Ln %1, Col %2\t%3"),
				gtk_text_iter_get_line(&iter) + 1,
				column + 1,
				gtk_text_view_get_overwrite(GTK_TEXT_VIEW(m_current_view->get_text_view())) ? _("OVR") : _("INS")
			)
		);
	}
}
<commit_msg>Don't show the same statusbar message more than once<commit_after>/* Gobby - GTK-based collaborative text editor
 * Copyright (C) 2008-2014 Armin Burgmeier <armin@arbur.net>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "core/statusbar.hpp"
#include "util/gtk-compat.hpp"
#include "util/i18n.hpp"

#include <glibmm/main.h>
#include <gtkmm/frame.h>
#include <gtkmm/stock.h>

namespace
{
	Gtk::StockID
	message_type_to_stock_id(Gobby::StatusBar::MessageType type)
	{
		switch(type)
		{
		case Gobby::StatusBar::INFO:
			return Gtk::Stock::DIALOG_INFO;
		case Gobby::StatusBar::ERROR:
			return Gtk::Stock::DIALOG_ERROR;
		default:
			g_assert_not_reached();
		}
	}

	void dispose_dialog(Gtk::MessageDialog* dialog)
	{
		delete dialog;
	}
}

class Gobby::StatusBar::Message
{
public:
	Message(Gtk::Widget* widget,
	        const Glib::ustring& simple,
	        const Glib::ustring& detail,
		sigc::connection timeout_conn = sigc::connection()):
		m_widget(widget), m_timeout_conn(timeout_conn),
		m_simple_desc(simple), m_detail_desc(detail)
	{
	}

	~Message()
	{
		m_timeout_conn.disconnect();
	}

	void show_dialog() const
	{
		Gtk::MessageDialog* dialog = new Gtk::MessageDialog(
			m_simple_desc,
			false,
			Gtk::MESSAGE_ERROR,
			Gtk::BUTTONS_NONE,
			false);

		dialog->add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);

		dialog->set_secondary_text(m_detail_desc, true);
		dialog->signal_response().connect(
			sigc::hide(
				sigc::bind(
					sigc::ptr_fun(dispose_dialog),
					dialog)));
		dialog->show();
	}

	bool is_error() { return !m_detail_desc.empty(); }

	const Glib::ustring& get_simple_text() const { return m_simple_desc; }
	const Glib::ustring& get_detail_text() const { return m_detail_desc; }

	Gtk::Widget* widget() const { return m_widget; }

protected:
	Gtk::Widget* m_widget;
	sigc::connection m_timeout_conn;
	Glib::ustring m_simple_desc;
	Glib::ustring m_detail_desc;
};

Gobby::StatusBar::StatusBar(Gtk::Window& window,
                            const Folder& folder,
                            const Preferences& preferences):
	Gtk::HBox(false, 2), m_folder(folder), m_preferences(preferences),
	m_visible_messages(0), m_current_view(NULL), m_position_context_id(0)
{
	pack_end(m_bar_position, Gtk::PACK_SHRINK);
	m_bar_position.set_size_request(200, -1);
	m_bar_position.show();

	window.signal_window_state_event().connect(
		sigc::mem_fun(*this, &StatusBar::on_window_state_event));

	m_folder.signal_document_removed().connect(
		sigc::mem_fun(*this, &StatusBar::on_document_removed));
	m_folder.signal_document_changed().connect(
		sigc::mem_fun(*this, &StatusBar::on_document_changed));
	m_preferences.appearance.show_statusbar.signal_changed().connect(
		sigc::mem_fun(*this, &StatusBar::on_view_changed));

	// Initial update
	on_document_changed(m_folder.get_current_document());
	on_view_changed();
}

Gobby::StatusBar::~StatusBar()
{
	on_document_changed(NULL);
}

Gobby::StatusBar::MessageHandle
Gobby::StatusBar::add_message(Gobby::StatusBar::MessageType type,
                              const Glib::ustring& message,
                              const Glib::ustring& dialog_message,
                              unsigned int timeout)
{
	if(m_visible_messages >= 12)
	{
		for(MessageHandle iter = m_list.begin();
		    iter != m_list.end();
		    ++iter)
		{
			if(*iter)
			{
				if((*iter)->is_error())
					remove_message(iter);
				else
					// only hide message because whoever
					// installed it is expecting to be
					// able to call remove_message on it
					hide_message(iter);
				break;
			}
		}
	}

	Gtk::HBox* bar = Gtk::manage(new Gtk::HBox);

	Gtk::Image* image = Gtk::manage(new Gtk::Image(
		message_type_to_stock_id(type), Gtk::ICON_SIZE_MENU));
	bar->pack_start(*image, Gtk::PACK_SHRINK);
	image->show();

	Gtk::Label* label = Gtk::manage(
		new Gtk::Label(message, GtkCompat::ALIGN_LEFT));
	label->set_ellipsize(Pango::ELLIPSIZE_END);
	bar->pack_start(*label, Gtk::PACK_EXPAND_WIDGET);
	label->show();

	GtkShadowType shadow_type;
	gtk_widget_style_get(GTK_WIDGET(m_bar_position.gobj()),
	                     "shadow-type", &shadow_type, NULL);
	Gtk::Frame* frame = Gtk::manage(new Gtk::Frame);

	m_list.push_back(0);
	Gobby::StatusBar::MessageHandle iter(--m_list.end());
	sigc::connection timeout_conn;
	if(timeout)
	{
		timeout_conn = Glib::signal_timeout().connect_seconds(
			sigc::bind(
				sigc::bind_return(
					sigc::mem_fun(
						*this,
						&StatusBar::remove_message),
					false),
				iter),
			timeout);
	}
	*iter = new Message(frame, message, dialog_message, timeout_conn);
	++m_visible_messages;

	if(dialog_message.empty())
	{
		frame->add(*bar);
	}
	else
	{
		Gtk::EventBox *eventbox = Gtk::manage(new Gtk::EventBox);
		frame->add(*eventbox);
		eventbox->add(*bar);
		eventbox->signal_button_press_event().connect(
			sigc::bind_return(sigc::bind(
				sigc::mem_fun(
					*this,
					&StatusBar::on_message_clicked),
				iter), false));

		eventbox->show();
	}

	frame->set_shadow_type(static_cast<Gtk::ShadowType>(shadow_type));
	bar->show();

	pack_start(*frame, Gtk::PACK_EXPAND_WIDGET);
	reorder_child(*frame, 0);

	frame->show();

	return iter;
}

Gobby::StatusBar::MessageHandle
Gobby::StatusBar::add_info_message(const Glib::ustring& message,
                                   unsigned int timeout)
{
	MessageHandle handle =
		Gobby::StatusBar::add_message(INFO, message, "", timeout);
	// Caller is not allowed to hold on to handles to messages that we are
	// going to delete anyway.
	if(timeout)
		return invalid_handle();
	else
		return handle;
}

void
Gobby::StatusBar::add_error_message(const Glib::ustring& brief_desc,
                                    const Glib::ustring& detailed_desc,
                                    unsigned int timeout)
{
	MessageHandle next;
	for(MessageHandle iter = m_list.begin(); iter != m_list.end(); iter = next)
	{
		next = iter;
		++next;

		if(*iter && (*iter)->is_error())
		{
			if( (*iter)->get_simple_text() == brief_desc)
			{
				remove_message(iter);
			}
		}
	}

	Gobby::StatusBar::add_message(ERROR,
	                              brief_desc,
	                              detailed_desc,
	                              timeout);
}

void Gobby::StatusBar::remove_message(const MessageHandle& handle)
{
	hide_message(handle);
	m_list.erase(handle);
}

void Gobby::StatusBar::hide_message(const MessageHandle& handle)
{
	if(*handle != 0)
	{
		g_assert(m_visible_messages > 0);
		--m_visible_messages;
		remove(*(*handle)->widget());
		delete *handle;
		*handle = 0;
	}
}

Gobby::StatusBar::MessageHandle Gobby::StatusBar::invalid_handle()
{
	return m_list.end();
}

void Gobby::StatusBar::on_message_clicked(GdkEventButton* button,
                                          const MessageHandle& handle)
{
	if(button->button == 1)
		(*handle)->show_dialog();

	remove_message(handle);
}

void Gobby::StatusBar::on_document_removed(SessionView& view)
{
	if(m_current_view == &view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		g_signal_handler_disconnect(buffer, m_mark_set_handler);
		g_signal_handler_disconnect(buffer, m_changed_handler);
		g_signal_handler_disconnect(m_current_view->get_text_view(),
		                            m_toverwrite_handler);

		m_current_view = NULL;
	}
}

void Gobby::StatusBar::on_document_changed(SessionView* view)
{
	if(m_current_view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		g_signal_handler_disconnect(buffer, m_mark_set_handler);
		g_signal_handler_disconnect(buffer, m_changed_handler);
		g_signal_handler_disconnect(m_current_view->get_text_view(),
		                            m_toverwrite_handler);
	}

	m_current_view = dynamic_cast<TextSessionView*>(view);

	if(m_current_view)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		m_mark_set_handler = g_signal_connect_after(
			G_OBJECT(buffer), "mark-set",
			G_CALLBACK(on_mark_set_static), this);

		m_changed_handler = g_signal_connect_after(
			G_OBJECT(buffer), "changed",
			G_CALLBACK(on_changed_static), this);

		m_toverwrite_handler = g_signal_connect_after(
			G_OBJECT(m_current_view->get_text_view()),
			"notify::overwrite",
			G_CALLBACK(on_toggled_overwrite_static), this);
	}

	// Initial update
	update_pos_display();
}

void Gobby::StatusBar::on_view_changed()
{
	if(m_preferences.appearance.show_statusbar) show();
	else hide();
}

void Gobby::StatusBar::on_mark_set(GtkTextMark* mark)
{
	GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
		m_current_view->get_text_buffer());

	if(mark == gtk_text_buffer_get_insert(buffer))
		update_pos_display();
}

void Gobby::StatusBar::on_toggled_overwrite()
{
	update_pos_display();
}

void Gobby::StatusBar::on_changed()
{
	update_pos_display();
}

bool Gobby::StatusBar::on_window_state_event(GdkEventWindowState* event)
{
	// In GTK+ 3 the resize grip is handled by the Window,
	// not the status bar
#ifndef USE_GTKMM3
	if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
		m_bar_position.set_has_resize_grip(false);
	else
		m_bar_position.set_has_resize_grip(true);
#endif

	return true;
}

void Gobby::StatusBar::update_pos_display()
{
	if(m_position_context_id)
		m_bar_position.remove_message(m_position_context_id);

	if(m_current_view != NULL)
	{
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());
		GtkTextIter iter;

		// TODO: Use TextSessionView::get_cursor_position()?
		gtk_text_buffer_get_iter_at_mark(
			buffer, &iter, gtk_text_buffer_get_insert(buffer));

		gint offset = gtk_text_iter_get_line_offset(&iter);

		unsigned int column = 0;
		const unsigned int tab_width = m_preferences.editor.tab_width;
		for(gtk_text_iter_set_line_offset(&iter, 0);
		    gtk_text_iter_get_line_offset(&iter) < offset;
		    gtk_text_iter_forward_char(&iter))
		{
			if(gtk_text_iter_get_char(&iter) == '\t')
				column += (tab_width - column % tab_width);
			else
				++ column;
		}

		// TODO: We might want to have a separate widget for the
		// OVR/INS display.
		m_position_context_id = m_bar_position.push(
			Glib::ustring::compose(
				_("Ln %1, Col %2\t%3"),
				gtk_text_iter_get_line(&iter) + 1,
				column + 1,
				gtk_text_view_get_overwrite(GTK_TEXT_VIEW(m_current_view->get_text_view())) ? _("OVR") : _("INS")
			)
		);
	}
}
<|endoftext|>