<commit_before>/**
 * @file
 *
 * @brief Source for simplespeclang plugin
 *
 * @copyright BSD License (see doc/COPYING or http://www.libelektra.org)
 *
 */

#include "simplespeclang.hpp"

using namespace ckdb;

#include <kdbease.h>
#include <kdberrors.h>

#include <kdbmeta.h>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>


namespace
{

std::string getConfigEnum (Plugin * handle)
{
	Key * k = ksLookupByName (elektraPluginGetConfig (handle), "/keyword/enum", 0);
	if (!k) return "enum";

	return keyString (k);
}

std::string getConfigAssign (Plugin * handle)
{
	Key * k = ksLookupByName (elektraPluginGetConfig (handle), "/keyword/assign", 0);
	if (!k) return "=";

	return keyString (k);
}

int serialise (std::ostream & os, ckdb::Key * parentKey, ckdb::KeySet * ks, Plugin * handle)
{
	ckdb::Key * cur;

	ksRewind (ks);
	while ((cur = ksNext (ks)) != nullptr)
	{
		const ckdb::Key * meta = ckdb::keyGetMeta (cur, "check/enum");
		if (!meta) continue;

		os << getConfigEnum (handle) << " ";
		os << elektraKeyGetRelativeName (cur, parentKey) << " ";
		os << getConfigAssign (handle);
		while ((meta = keyNextMeta (cur)))
		{
			os << " " << ckdb::keyString (meta);
		}
		os << "\n";
	}

	return 1;
}

int unserialise (std::istream & is, ckdb::Key * errorKey, ckdb::KeySet * ks, Plugin * handle)
{
	Key * cur = nullptr;

	Key * parent = keyNew (keyName (errorKey), KEY_END);

	std::string line;
	while (std::getline (is, line))
	{
		std::string read;
		std::stringstream ss (line);
		ss >> read;
		if (read == "mountpoint")
		{
			ss >> read;
			keySetMeta (parent, "mountpoint", read.c_str ());
			continue;
		}
		else if (read == "plugins")
		{
			std::string plugins;
			while (ss >> read)
			{
				// replace (read.begin(), read.end(), '_', ' ');
				plugins += read + " ";
			}
			keySetMeta (parent, "infos/plugins", plugins.c_str ());
			continue;
		}
		else if (read != getConfigEnum (handle))
		{
			ELEKTRA_LOG ("not an enum %s", read.c_str ());
			continue;
		}

		std::string name;
		ss >> name;
		ELEKTRA_LOG ("key name for enum is %s", name.c_str ());
		cur = keyNew (keyName (errorKey), KEY_END);
		keyAddName (cur, name.c_str ());

		ss >> read;
		if (read != getConfigAssign (handle))
		{
			ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_PARSE, errorKey, "Expected assignment (%s), but got (%s)",
					    getConfigAssign (handle).c_str (), read.c_str ());
			continue;
		}

		int added = 0;
		while (ss >> read)
		{
			++added;
			elektraMetaArrayAdd (cur, "check/enum", read.c_str ());
		}

		if (added)
		{
			ELEKTRA_LOG ("%s is enum with %d entries (last char is %c)", name.c_str (), added, name.back ());
			keySetMeta (cur, "check/enum", "#");
			if (name.back () == '*')
			{
				keySetMeta (cur, "check/enum/multi", " ");
			}
		}

		keySetMeta (cur, "required", "yes"); // TODO bug: required key removed by spec?
		keySetMeta (cur, "mandatory", "yes");

		ckdb::ksAppendKey (ks, cur);
	}
<commit_msg>simplespeclang: also set require<commit_after>/**
 * @file
 *
 * @brief Source for simplespeclang plugin
 *
 * @copyright BSD License (see doc/COPYING or http://www.libelektra.org)
 *
 */

#include "simplespeclang.hpp"

using namespace ckdb;

#include <kdbease.h>
#include <kdberrors.h>

#include <kdbmeta.h>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>


namespace
{

std::string getConfigEnum (Plugin * handle)
{
	Key * k = ksLookupByName (elektraPluginGetConfig (handle), "/keyword/enum", 0);
	if (!k) return "enum";

	return keyString (k);
}

std::string getConfigAssign (Plugin * handle)
{
	Key * k = ksLookupByName (elektraPluginGetConfig (handle), "/keyword/assign", 0);
	if (!k) return "=";

	return keyString (k);
}

int serialise (std::ostream & os, ckdb::Key * parentKey, ckdb::KeySet * ks, Plugin * handle)
{
	ckdb::Key * cur;

	ksRewind (ks);
	while ((cur = ksNext (ks)) != nullptr)
	{
		const ckdb::Key * meta = ckdb::keyGetMeta (cur, "check/enum");
		if (!meta) continue;

		os << getConfigEnum (handle) << " ";
		os << elektraKeyGetRelativeName (cur, parentKey) << " ";
		os << getConfigAssign (handle);
		while ((meta = keyNextMeta (cur)))
		{
			os << " " << ckdb::keyString (meta);
		}
		os << "\n";
	}

	return 1;
}

int unserialise (std::istream & is, ckdb::Key * errorKey, ckdb::KeySet * ks, Plugin * handle)
{
	Key * cur = nullptr;

	Key * parent = keyNew (keyName (errorKey), KEY_END);

	std::string line;
	while (std::getline (is, line))
	{
		std::string read;
		std::stringstream ss (line);
		ss >> read;
		if (read == "mountpoint")
		{
			ss >> read;
			keySetMeta (parent, "mountpoint", read.c_str ());
			continue;
		}
		else if (read == "plugins")
		{
			std::string plugins;
			while (ss >> read)
			{
				// replace (read.begin(), read.end(), '_', ' ');
				plugins += read + " ";
			}
			keySetMeta (parent, "infos/plugins", plugins.c_str ());
			continue;
		}
		else if (read != getConfigEnum (handle))
		{
			ELEKTRA_LOG ("not an enum %s", read.c_str ());
			continue;
		}

		std::string name;
		ss >> name;
		ELEKTRA_LOG ("key name for enum is %s", name.c_str ());
		cur = keyNew (keyName (errorKey), KEY_END);
		keyAddName (cur, name.c_str ());

		ss >> read;
		if (read != getConfigAssign (handle))
		{
			ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_PARSE, errorKey, "Expected assignment (%s), but got (%s)",
					    getConfigAssign (handle).c_str (), read.c_str ());
			continue;
		}

		int added = 0;
		while (ss >> read)
		{
			++added;
			elektraMetaArrayAdd (cur, "check/enum", read.c_str ());
		}

		if (added)
		{
			ELEKTRA_LOG ("%s is enum with %d entries (last char is %c)", name.c_str (), added, name.back ());
			keySetMeta (cur, "check/enum", "#");
			if (name.back () == '*')
			{
				keySetMeta (cur, "check/enum/multi", " ");
			}
		}

		keySetMeta (cur, "required", "yes"); // TODO bug: required key removed by spec?
		keySetMeta (cur, "require", "yes");
		keySetMeta (cur, "mandatory", "yes");

		ckdb::ksAppendKey (ks, cur);
	}

{'fraction_non_alphanumeric': 0.180720871751886, 'fraction_numerical': 0.001341156747694887, 'mean_word_length': 3.568147013782542, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '6978093', 'n_tokens_mistral': 2494, 'n_tokens_neox': 2244, 'n_words': 573}