<commit_before>/**
 * @file
 *
 * @brief A plugin that makes use of libaugeas to read and write configuration files
 *
 * @copyright BSD License (see doc/LICENSE.md or http://www.libelektra.org)
 *
 */

#ifndef HAVE_KDBCONFIG
#include "kdbconfig.h"
#endif

/* used for asprintf */
#define _GNU_SOURCE

#include <ctype.h>
#include <glob.h>
#include <libgen.h>

#include "aug.h"

#define ELEKTRA_SET_GENERAL_ERROR(id, parentKey, message)                                                                                  \
	do                                                                                                                                 \
	{                                                                                                                                  \
		ELEKTRA_SET_ERROR (id, parentKey, message);                                                                                \
		errno = errnosave;                                                                                                         \
		return -1;                                                                                                                 \
	} while (0)

#define ELEKTRA_SET_ERRNO_ERROR(id, parentKey) ELEKTRA_SET_GENERAL_ERROR (id, parentKey, strerror (errno))

#define ELEKTRA_SET_AUGEAS_ERROR(handle, parrentKey) ELEKTRA_SET_GENERAL_ERROR (85, parentKey, getAugeasError (augeasHandle))

struct KeyConversion
{
	KeySet * ks;
	Key * parentKey;
	int currentOrder;
};

struct OrphanSearch
{
	KeySet * ks;
	Key * parentKey;
};

typedef int (*ForeachAugNodeClb) (augeas *, const char *, void *);

int keySetOrderMeta (Key * key, int order)
{
	char * buffer;
	int result;
	result = asprintf (&buffer, "%d", order);

	if (result < 0) return result;

	result = keySetMeta (key, "order", buffer);
	elektraFree (buffer);
	return result;
}

static int keyCmpOrderWrapper (const void * a, const void * b)
{
	return elektraKeyCmpOrder (*((const Key **)a), *((const Key **)b));
}

static const char * getLensPath (Plugin * handle)
{
	KeySet * config = elektraPluginGetConfig (handle);
	Key * lensPathKey = ksLookupByName (config, "/lens", 0);
	return keyString (lensPathKey);
}

int elektraAugeasGenConf (KeySet * ks, Key * errorKey ELEKTRA_UNUSED)
{
	glob_t pglob;
	int retval = 1;
	const char * f = "/usr/share/augeas/lenses/dist/*.aug";
	if (glob (f, GLOB_NOSORT, NULL, &pglob) == 0)
	{
		ELEKTRA_LOG ("has glob %zd", pglob.gl_pathc);
		for (size_t i = 0; i < pglob.gl_pathc; ++i)
		{
			char * p = elektraStrDup (basename (pglob.gl_pathv[i]));
			size_t l = strlen (p);
			if (l > 4)
			{
				p[l - 4] = '\0';
				Key * k = keyNew ("system/", KEY_END);
				keyAddBaseName (k, p);
				ksAppendKey (ks, keyDup (k));

				Key * b = keyDup (k);
				keyAddBaseName (b, "infos");
				ksAppendKey (ks, keyDup (b));
				keyAddBaseName (b, "provides");
				char * s = elektraFormat ("storage/%s", p);
				keySetString (b, s);
				elektraFree (s);
				ksAppendKey (ks, b);

				keyAddBaseName (k, "config");
				ksAppendKey (ks, keyDup (k));
				keyAddBaseName (k, "lens");
				p[0] = toupper (p[0]);
				p[l - 1] = 's';
				p[l - 2] = 'n';
				p[l - 3] = 'l';
				p[l - 4] = '.';
				keySetString (k, p);
				ksAppendKey (ks, k);
			}
			elektraFree (p);
		}
		globfree (&pglob);
	}
	else
	{
		ELEKTRA_SET_ERRORF (142, errorKey, "Could not glob %s", f);
		retval = -1;
	}
	return retval;
}

static const char * getAugeasError (augeas * augeasHandle)
{
	const char * reason = 0;
	if (aug_error (augeasHandle) != 0)
	{
		reason = aug_error_message (augeasHandle);
	}
	else
	{
		const char * augeasError;
		aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error", &augeasError);

		if (augeasError)
		{
			const char * lens;
			const char * line;
			const char * character;
			const char * message;

			aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/lens", &lens);
			aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/line", &line);
			aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/char", &character);
			aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/message", &message);

			const char * format = "%s\n\tposition: %s:%s\n\tmessage: %s\n\tlens: %s";
			size_t messageSize = strlen (augeasError) + strlen (line) + strlen (character) + strlen (message) + strlen (lens) +
					     strlen (format);
			char * buffer = elektraMalloc (messageSize);
			sprintf (buffer, format, augeasError, line, character, message, lens);
			reason = buffer;
		}
		else
		{
			reason = "No specific reason was reported";
		}
	}<commit_msg>augeas: fix error message again<commit_after>/**
 * @file
 *
 * @brief A plugin that makes use of libaugeas to read and write configuration files
 *
 * @copyright BSD License (see doc/LICENSE.md or http://www.libelektra.org)
 *
 */

#ifndef HAVE_KDBCONFIG
#include "kdbconfig.h"
#endif

/* used for asprintf */
#define _GNU_SOURCE

#include <ctype.h>
#include <glob.h>
#include <libgen.h>

#include "aug.h"

#define ELEKTRA_SET_GENERAL_ERROR(id, parentKey, message)                                                                                  \
	do                                                                                                                                 \
	{                                                                                                                                  \
		ELEKTRA_SET_ERROR (id, parentKey, message);                                                                                \
		errno = errnosave;                                                                                                         \
		return -1;                                                                                                                 \
	} while (0)

#define ELEKTRA_SET_ERRNO_ERROR(id, parentKey) ELEKTRA_SET_GENERAL_ERROR (id, parentKey, strerror (errno))

#define ELEKTRA_SET_AUGEAS_ERROR(handle, parrentKey) ELEKTRA_SET_GENERAL_ERROR (85, parentKey, getAugeasError (augeasHandle))

struct KeyConversion
{
	KeySet * ks;
	Key * parentKey;
	int currentOrder;
};

struct OrphanSearch
{
	KeySet * ks;
	Key * parentKey;
};

typedef int (*ForeachAugNodeClb) (augeas *, const char *, void *);

int keySetOrderMeta (Key * key, int order)
{
	char * buffer;
	int result;
	result = asprintf (&buffer, "%d", order);

	if (result < 0) return result;

	result = keySetMeta (key, "order", buffer);
	elektraFree (buffer);
	return result;
}

static int keyCmpOrderWrapper (const void * a, const void * b)
{
	return elektraKeyCmpOrder (*((const Key **)a), *((const Key **)b));
}

static const char * getLensPath (Plugin * handle)
{
	KeySet * config = elektraPluginGetConfig (handle);
	Key * lensPathKey = ksLookupByName (config, "/lens", 0);
	return keyString (lensPathKey);
}

int elektraAugeasGenConf (KeySet * ks, Key * errorKey ELEKTRA_UNUSED)
{
	glob_t pglob;
	int retval = 1;
	const char * f = "/usr/share/augeas/lenses/dist/*.aug";
	if (glob (f, GLOB_NOSORT, NULL, &pglob) == 0)
	{
		ELEKTRA_LOG ("has glob %zd", pglob.gl_pathc);
		for (size_t i = 0; i < pglob.gl_pathc; ++i)
		{
			char * p = elektraStrDup (basename (pglob.gl_pathv[i]));
			size_t l = strlen (p);
			if (l > 4)
			{
				p[l - 4] = '\0';
				Key * k = keyNew ("system/", KEY_END);
				keyAddBaseName (k, p);
				ksAppendKey (ks, keyDup (k));

				Key * b = keyDup (k);
				keyAddBaseName (b, "infos");
				ksAppendKey (ks, keyDup (b));
				keyAddBaseName (b, "provides");
				char * s = elektraFormat ("storage/%s", p);
				keySetString (b, s);
				elektraFree (s);
				ksAppendKey (ks, b);

				keyAddBaseName (k, "config");
				ksAppendKey (ks, keyDup (k));
				keyAddBaseName (k, "lens");
				p[0] = toupper (p[0]);
				p[l - 1] = 's';
				p[l - 2] = 'n';
				p[l - 3] = 'l';
				p[l - 4] = '.';
				keySetString (k, p);
				ksAppendKey (ks, k);
			}
			elektraFree (p);
		}
		globfree (&pglob);
	}
	else
	{
		ELEKTRA_SET_ERRORF (142, errorKey, "Could not glob %s", f);
		retval = -1;
	}
	return retval;
}

static const char * getAugeasError (augeas * augeasHandle)
{
	const char * reason = 0;
	if (aug_error (augeasHandle) != 0)
	{
		reason = aug_error_message (augeasHandle);
	}
	else
	{
		const char * augeasError;
		aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error", &augeasError);

		if (augeasError)
		{
			const char * lens;
			const char * line;
			const char * character;
			const char * message;

			aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/lens", &lens);
			aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/line", &line);
			aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/char", &character);
			aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/message", &message);

			const char * format = "%s\n\tposition: %s:%s\n\tmessage: %s\n\tlens: %s";
			size_t messageSize = (augeasError ? strlen (augeasError) : 0) + (line ? strlen (line) : 0) +
					     (character ? strlen (character) : 0) + (message ? strlen (message) : 0) +
					     (lens ? strlen (lens) : 0) + strlen (format);
			char * buffer = elektraMalloc (messageSize);
			snprintf (buffer, messageSize, format, augeasError ? augeasError : "", line ? line : "", character ? character : "",
				  message ? message : "", lens ? lens : "");
			reason = buffer;
		}
		else
		{
			reason = "No specific reason was reported";
		}
	}
{'fraction_non_alphanumeric': 0.1326237360298031, 'fraction_numerical': 0.00564129856306546, 'mean_word_length': 2.103038309114927, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 50, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4093147', 'n_tokens_mistral': 3488, 'n_tokens_neox': 3160, 'n_words': 822}