<commit_before>/**
 * \file
 *
 * \brief Source for the getenv library
 *
 * \note there are two necessary bootstrap phases:
 *
 * 1.) bootstrapping in pre-main phase when no allocation is possible
 * 2.) bootstrapping when elektra modules use getenv()
 *
 * \copyright BSD License (see doc/COPYING or http://www.libelektra.org)
 *
 */

#ifndef _GNU_SOURCE
# define _GNU_SOURCE // for RTLD_NEXT (except BSDI)
#endif


#include <kdbgetenv.h>
#include <kdbconfig.h>

#include <kdbcontext.hpp>

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <libgen.h>
#include <unistd.h> // euid
#include <sys/types.h> // euid

#include <string>
#include <chrono>
#include <sstream>
#include <iostream>

/* BSDI has this functionality, but its not defined */
#if !defined(RTLD_NEXT)
#define RTLD_NEXT ((void *) -1L)
#endif

using namespace std;
using namespace ckdb;

#define LOG if(elektraLog) (*elektraLog)

namespace ckdb
{

extern "C"
{
Key *elektraParentKey;
KeySet *elektraConfig;
KDB *elektraRepo;
} // extern "C"

namespace
{

class KeyValueLayer : public kdb::Layer
{
public:
	KeyValueLayer(std::string const & key, std::string const & value_) :
		m_key(key), m_value(value_) {}
	std::string id() const { return m_key; }
	std::string operator()() const { return m_value; }
private:
	std::string m_key;
	std::string m_value;
};

class GetEnvContext : public kdb::Context
{
public:
	void addLayer(std::string layername, std::string layervalue)
	{
		std::shared_ptr<kdb::Layer> layer = make_shared<KeyValueLayer>(layername, layervalue);
		activateLayer(layer);
	}
	void clearAllLayer()
	{
		kdb::Context::clearAllLayer();
	}
} elektraEnvContext;

typedef int (*fcn)(int *(main) (int, char * *, char * *), int argc, char ** argv, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end));
typedef char *(* gfcn)(const char *);

union Start{void*d; fcn f;} start; // symbol for libc pre-main
union Sym{void*d; gfcn f;} sym, ssym; // symbols for libc (secure) getenv

std::chrono::milliseconds elektraReloadTimeout;
std::chrono::system_clock::time_point elektraReloadNext;
std::shared_ptr<ostream>elektraLog;
bool elektraInGetEnv;
KeySet *elektraDocu = ksNew(20,
#include "readme_elektrify-getenv.c"
	KS_END);

#if defined(__APPLE__) && defined(__MACH__)
	pthread_mutex_t elektraGetEnvMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
#else
	pthread_mutex_t elektraGetEnvMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
#endif


int to_(int c)
{
	if (c == '-') return '_';
	return c;
}

} // anonymous namespace



extern "C" void elektraLockMutex()
{
	pthread_mutex_lock(&elektraGetEnvMutex);
}

extern "C" void elektraUnlockMutex()
{
	pthread_mutex_unlock(&elektraGetEnvMutex);
}



void printVersion()
{
	cout << "Elektra getenv is active" << std::endl;
	Key *k = keyNew("system/elektra/version", KEY_END);
	KDB *kdb = kdbOpen(k);
	KeySet *c = ksNew(20, KS_END);
	kdbGet (kdb, c, k);
	kdbClose(kdb, k);
	keyDel(k);
	Key *kdb_version = ksLookupByName(c, "system/elektra/version/constants/KDB_VERSION", 0);
	if (!kdb_version)
	{
		cerr << "Could not lookup KDB_VERSION key" << endl;
	}
	else
	{
		cout << "KDB_VERSION: " << keyString(kdb_version) << endl;
	}
	cout << "KDB_GETENV_VERSION: " << KDB_GETENV_VERSION << endl;
	ksDel(c);
}

void addOverride(string kv)
{
	stringstream ss(kv);<commit_msg>getenv: add compile time option if locks are used<commit_after>/**
 * \file
 *
 * \brief Source for the getenv library
 *
 * \note there are two necessary bootstrap phases:
 *
 * 1.) bootstrapping in pre-main phase when no allocation is possible
 * 2.) bootstrapping when elektra modules use getenv()
 *
 * \copyright BSD License (see doc/COPYING or http://www.libelektra.org)
 *
 */

#ifndef _GNU_SOURCE
# define _GNU_SOURCE // for RTLD_NEXT (except BSDI)
#endif

#define ELEKTRA_GETENV_USE_LOCKS 0


#include <kdbgetenv.h>
#include <kdbconfig.h>

#include <kdbcontext.hpp>

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <libgen.h>
#include <unistd.h> // euid
#include <sys/types.h> // euid

#include <string>
#include <chrono>
#include <sstream>
#include <iostream>

/* BSDI has this functionality, but its not defined */
#if !defined(RTLD_NEXT)
#define RTLD_NEXT ((void *) -1L)
#endif

using namespace std;
using namespace ckdb;

#define LOG if(elektraLog) (*elektraLog)

namespace ckdb
{

extern "C"
{
Key *elektraParentKey;
KeySet *elektraConfig;
KDB *elektraRepo;
} // extern "C"

namespace
{

class KeyValueLayer : public kdb::Layer
{
public:
	KeyValueLayer(std::string const & key, std::string const & value_) :
		m_key(key), m_value(value_) {}
	std::string id() const { return m_key; }
	std::string operator()() const { return m_value; }
private:
	std::string m_key;
	std::string m_value;
};

class GetEnvContext : public kdb::Context
{
public:
	void addLayer(std::string layername, std::string layervalue)
	{
		std::shared_ptr<kdb::Layer> layer = make_shared<KeyValueLayer>(layername, layervalue);
		activateLayer(layer);
	}
	void clearAllLayer()
	{
		kdb::Context::clearAllLayer();
	}
} elektraEnvContext;

typedef int (*fcn)(int *(main) (int, char * *, char * *), int argc, char ** argv, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end));
typedef char *(* gfcn)(const char *);

union Start{void*d; fcn f;} start; // symbol for libc pre-main
union Sym{void*d; gfcn f;} sym, ssym; // symbols for libc (secure) getenv

std::chrono::milliseconds elektraReloadTimeout;
std::chrono::system_clock::time_point elektraReloadNext;
std::shared_ptr<ostream>elektraLog;
bool elektraInGetEnv;
KeySet *elektraDocu = ksNew(20,
#include "readme_elektrify-getenv.c"
	KS_END);

int to_(int c)
{
	if (c == '-') return '_';
	return c;
}


#if ELEKTRA_GETENV_USE_LOCKS
# if defined(__APPLE__) && defined(__MACH__)
	pthread_mutex_t elektraGetEnvMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
# else
	pthread_mutex_t elektraGetEnvMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
# endif
#endif



} // anonymous namespace



extern "C" void elektraLockMutex()
{
#if ELEKTRA_GETENV_USE_LOCKS
	pthread_mutex_lock(&elektraGetEnvMutex);
#endif
}

extern "C" void elektraUnlockMutex()
{
#if ELEKTRA_GETENV_USE_LOCKS
	pthread_mutex_unlock(&elektraGetEnvMutex);
#endif
}



void printVersion()
{
	cout << "Elektra getenv is active" << std::endl;
	Key *k = keyNew("system/elektra/version", KEY_END);
	KDB *kdb = kdbOpen(k);
	KeySet *c = ksNew(20, KS_END);
	kdbGet (kdb, c, k);
	kdbClose(kdb, k);
	keyDel(k);
	Key *kdb_version = ksLookupByName(c, "system/elektra/version/constants/KDB_VERSION", 0);
	if (!kdb_version)
	{
		cerr << "Could not lookup KDB_VERSION key" << endl;
	}
	else
	{
		cout << "KDB_VERSION: " << keyString(kdb_version) << endl;
	}
	cout << "KDB_GETENV_VERSION: " << KDB_GETENV_VERSION << endl;
	ksDel(c);
}

void addOverride(string kv)
{
	stringstream ss(kv);
{'fraction_non_alphanumeric': 0.1435793731041456, 'fraction_numerical': 0.002455582839809331, 'mean_word_length': 5.243462578899909, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 39, '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': '4012480', 'n_tokens_mistral': 2728, 'n_tokens_neox': 2673, 'n_words': 639}