<commit_before>#include "luatool.h"
#include "ensemble.h"
#include "forecast_time.h"
#include "hitool.h"
#include "lagged_ensemble.h"
#include "latitude_longitude_grid.h"
#include "logger.h"
#include "metutil.h"
#include "numerical_functions.h"
#include "plugin_factory.h"
#include "radon.h"
#include "reduced_gaussian_grid.h"
#include "stereographic_grid.h"
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>

#ifndef __clang_analyzer__

extern "C" {
#include <lualib.h>
}

#include <luabind/adopt_policy.hpp>
#include <luabind/iterator_policy.hpp>
#include <luabind/luabind.hpp>
#include <luabind/operator.hpp>

// void ScherlokHoms(info_t& myTargetInfo){std::cout<<myTargetInfo->Data().MissingValue() <<'\n';}

using namespace himan;
using namespace himan::plugin;
using namespace luabind;

#define LUA_MEMFN(r, t, m, ...) static_cast<r (t::*)(__VA_ARGS__)>(&t::m)
#define LUA_CMEMFN(r, t, m, ...) static_cast<r (t::*)(__VA_ARGS__) const>(&t::m)

void BindEnum(lua_State* L);
int BindErrorHandler(lua_State* L);
void BindPlugins(lua_State* L);
void BindLib(lua_State* L);

object VectorToTable(const std::vector<double>& vec);
std::vector<double> TableToVector(const object& table);

boost::thread_specific_ptr<lua_State> myL;

luatool::luatool() : itsWriteOptions()
{
	itsLogger = logger("luatool");
	myL.reset();
}

luatool::~luatool()
{
}
void luatool::Process(std::shared_ptr<const plugin_configuration> conf)
{
	Init(conf);

	SetParams({param("DUMMY")});

	Start();
}

void luatool::Calculate(std::shared_ptr<info> myTargetInfo, unsigned short threadIndex)
{
	auto myThreadedLogger = logger("luatoolThread #" + std::to_string(threadIndex));

	InitLua();

	ASSERT(myL.get());
	myThreadedLogger.Info("Calculating time " + static_cast<std::string>(myTargetInfo->Time().ValidDateTime()) +
	                      " level " + static_cast<std::string>(myTargetInfo->Level()));

	globals(myL.get())["logger"] = myThreadedLogger;

	for (const std::string& luaFile : itsConfiguration->GetValueList("luafile"))
	{
		if (luaFile.empty())
		{
			continue;
		}

		myThreadedLogger.Info("Starting script " + luaFile);

		ResetVariables(myTargetInfo);
		ReadFile(luaFile);
	}

	lua_close(myL.get());
	myL.release();
}

void luatool::InitLua()
{
	lua_State* L = luaL_newstate();

	ASSERT(L);

	luaL_openlibs(L);

	open(L);

	set_pcall_callback(&BindErrorHandler);

	BindEnum(L);
	BindLib(L);
	BindPlugins(L);

	myL.reset(L);
}

void luatool::ResetVariables(info_t myTargetInfo)
{
	// Set some variable that are needed in luatool calculations
	// but are too hard or complicated to create in the lua side

	const auto L = myL.get();

	// Create new data vector after successive calls to ResetVariables()
	auto localInfo = std::make_shared<info> (*myTargetInfo);
	localInfo->Create(localInfo->Grid());

	globals(L)["luatool"] = boost::ref(*this);
	globals(L)["result"] = localInfo;
	globals(L)["configuration"] = itsConfiguration;
	globals(L)["write_options"] = boost::ref(itsWriteOptions);

	// Useful variables
	globals(L)["current_time"] = forecast_time(myTargetInfo->Time());
	globals(L)["current_level"] = level(myTargetInfo->Level());
	globals(L)["current_forecast_type"] = forecast_type(myTargetInfo->ForecastType());
	globals(L)["missing"] = MissingDouble();
<commit_msg>Revert "Create a new data vector between calls for lua script execution"<commit_after>#include "luatool.h"
#include "ensemble.h"
#include "forecast_time.h"
#include "hitool.h"
#include "lagged_ensemble.h"
#include "latitude_longitude_grid.h"
#include "logger.h"
#include "metutil.h"
#include "numerical_functions.h"
#include "plugin_factory.h"
#include "radon.h"
#include "reduced_gaussian_grid.h"
#include "stereographic_grid.h"
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>

#ifndef __clang_analyzer__

extern "C" {
#include <lualib.h>
}

#include <luabind/adopt_policy.hpp>
#include <luabind/iterator_policy.hpp>
#include <luabind/luabind.hpp>
#include <luabind/operator.hpp>

// void ScherlokHoms(info_t& myTargetInfo){std::cout<<myTargetInfo->Data().MissingValue() <<'\n';}

using namespace himan;
using namespace himan::plugin;
using namespace luabind;

#define LUA_MEMFN(r, t, m, ...) static_cast<r (t::*)(__VA_ARGS__)>(&t::m)
#define LUA_CMEMFN(r, t, m, ...) static_cast<r (t::*)(__VA_ARGS__) const>(&t::m)

void BindEnum(lua_State* L);
int BindErrorHandler(lua_State* L);
void BindPlugins(lua_State* L);
void BindLib(lua_State* L);

object VectorToTable(const std::vector<double>& vec);
std::vector<double> TableToVector(const object& table);

boost::thread_specific_ptr<lua_State> myL;

luatool::luatool() : itsWriteOptions()
{
	itsLogger = logger("luatool");
	myL.reset();
}

luatool::~luatool()
{
}
void luatool::Process(std::shared_ptr<const plugin_configuration> conf)
{
	Init(conf);

	SetParams({param("DUMMY")});

	Start();
}

void luatool::Calculate(std::shared_ptr<info> myTargetInfo, unsigned short threadIndex)
{
	auto myThreadedLogger = logger("luatoolThread #" + std::to_string(threadIndex));

	InitLua();

	ASSERT(myL.get());
	myThreadedLogger.Info("Calculating time " + static_cast<std::string>(myTargetInfo->Time().ValidDateTime()) +
	                      " level " + static_cast<std::string>(myTargetInfo->Level()));

	globals(myL.get())["logger"] = myThreadedLogger;

	for (const std::string& luaFile : itsConfiguration->GetValueList("luafile"))
	{
		if (luaFile.empty())
		{
			continue;
		}

		myThreadedLogger.Info("Starting script " + luaFile);

		ResetVariables(myTargetInfo);
		ReadFile(luaFile);
	}

	lua_close(myL.get());
	myL.release();
}

void luatool::InitLua()
{
	lua_State* L = luaL_newstate();

	ASSERT(L);

	luaL_openlibs(L);

	open(L);

	set_pcall_callback(&BindErrorHandler);

	BindEnum(L);
	BindLib(L);
	BindPlugins(L);

	myL.reset(L);
}

void luatool::ResetVariables(info_t myTargetInfo)
{
	// Set some variable that are needed in luatool calculations
	// but are too hard or complicated to create in the lua side

	const auto L = myL.get();

	globals(L)["luatool"] = boost::ref(*this);
	globals(L)["result"] = myTargetInfo;
	globals(L)["configuration"] = itsConfiguration;
	globals(L)["write_options"] = boost::ref(itsWriteOptions);

	// Useful variables
	globals(L)["current_time"] = forecast_time(myTargetInfo->Time());
	globals(L)["current_level"] = level(myTargetInfo->Level());
	globals(L)["current_forecast_type"] = forecast_type(myTargetInfo->ForecastType());
	globals(L)["missing"] = MissingDouble();

{'fraction_non_alphanumeric': 0.16656327543424318, 'fraction_numerical': 0.0, 'mean_word_length': 6.498837209302326, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2468595', 'n_tokens_mistral': 2427, 'n_tokens_neox': 2347, 'n_words': 421}