<commit_before>#include "pub/mem.h"
#include "context.h"
#include "err.h"

#define GET_CONTEXT(chain_sub) ((chain_sub)->ct)

typedef struct ivm_ctchain_sub_t_tag ivm_ctchain_sub_t;

static
ivm_ctchain_sub_t *
ivm_ctchain_sub_new(ivm_context_t *ct)
{
	ivm_ctchain_sub_t *ret = MEM_ALLOC(sizeof(*ret));

	IVM_ASSERT(ret, IVM_ERROR_MSG_FAILED_ALLOC_NEW("sub context chain"));

	ret->ct = ct;
	ret->outer = ret->inner = IVM_NULL;

	return ret;
}

static
void
ivm_ctchain_sub_free(ivm_ctchain_sub_t *chain_sub)
{
	MEM_FREE(chain_sub);
	return;
}

#define FOREACH(i, chain) for ((i) = (chain)->head; (i); (i) = (i)->inner)
#define RFOREACH(i, chain) for ((i) = (chain)->tail; (i); (i) = (i)->outer)

ivm_ctchain_t *
ivm_ctchain_new()
{
	ivm_ctchain_t *ret = MEM_ALLOC(sizeof(*ret));

	IVM_ASSERT(ret, IVM_ERROR_MSG_FAILED_ALLOC_NEW("context chain"));

	ret->head = ret->tail = IVM_NULL;

	return ret;
}

void
ivm_ctchain_free(ivm_ctchain_t *chain)
{
	ivm_ctchain_sub_t *i, *tmp;

	if (chain) {
		for (i = chain->head; i;) {
			tmp = i;
			i = i->inner;
			ivm_ctchain_sub_free(tmp);
		}
		MEM_FREE(chain);
	}

	return;
}

void
ivm_ctchain_addContext(ivm_ctchain_t *chain,
					   ivm_context_t *ct)
{
	ivm_ctchain_sub_t *n_sub = ivm_ctchain_sub_new(ct);

	if (!chain->tail) {
		chain->head = chain->tail = n_sub;
	} else {
		chain->tail->inner = n_sub;
		n_sub->outer = chain->tail;
		chain->tail = n_sub;
	}

	return;
}

void
ivm_ctchain_removeContext(ivm_ctchain_t *chain,
						  ivm_context_t *ct)
{
	ivm_ctchain_sub_t *i;

	RFOREACH (i, chain) {
		if (i->ct == ct) {
			if (i->outer)
				i->outer->inner = i->inner;

			if (i->inner)
				i->inner->outer = i->outer;

			if (i == chain->head)
				chain->head = i->inner;

			if (i == chain->tail)
				chain->tail = i->outer;

			ivm_ctchain_sub_free(i);

			break;
		}
	}

	return;
}

ivm_object_t *
ivm_ctchain_search(ivm_ctchain_t *chain,
				   struct ivm_vmstate_t_tag *state,
				   const ivm_char_t *key)
{
	ivm_slot_t *slot = ivm_ctchain_searchSlot(chain, state, key);

	return slot ? ivm_slot_getValue(slot, state) : IVM_NULL;
}

ivm_slot_t *
ivm_ctchain_searchSlot(ivm_ctchain_t *chain,
					   struct ivm_vmstate_t_tag *state,
					   const ivm_char_t *key)
{
	ivm_slot_t *slot = IVM_NULL;
	ivm_ctchain_sub_t *i;

	RFOREACH (i, chain) {
		printf("test1: %p\n", i);
		slot = ivm_object_getSlot(GET_CONTEXT(i), state, key);
		if (slot && ivm_slot_getValue(slot, state))
			return slot;
	}

	return IVM_NULL;
}

ivm_ctchain_t *
ivm_ctchain_clone(ivm_ctchain_t *chain)
{
	ivm_ctchain_t *ret;
	ivm_ctchain_sub_t *i;

	if (!chain)
		return IVM_NULL;

	ret = ivm_ctchain_new();

	FOREACH (i, chain) {
		ivm_ctchain_addContext(ret, GET_CONTEXT(i));
	}

	return ret;
}

void
ivm_ctchain_foreach(ivm_ctchain_t *chain,
					ivm_ctchain_foreach_proc_t proc,<commit_msg>040516#02: remove a test print<commit_after>#include "pub/mem.h"
#include "context.h"
#include "err.h"

#define GET_CONTEXT(chain_sub) ((chain_sub)->ct)

typedef struct ivm_ctchain_sub_t_tag ivm_ctchain_sub_t;

static
ivm_ctchain_sub_t *
ivm_ctchain_sub_new(ivm_context_t *ct)
{
	ivm_ctchain_sub_t *ret = MEM_ALLOC(sizeof(*ret));

	IVM_ASSERT(ret, IVM_ERROR_MSG_FAILED_ALLOC_NEW("sub context chain"));

	ret->ct = ct;
	ret->outer = ret->inner = IVM_NULL;

	return ret;
}

static
void
ivm_ctchain_sub_free(ivm_ctchain_sub_t *chain_sub)
{
	MEM_FREE(chain_sub);
	return;
}

#define FOREACH(i, chain) for ((i) = (chain)->head; (i); (i) = (i)->inner)
#define RFOREACH(i, chain) for ((i) = (chain)->tail; (i); (i) = (i)->outer)

ivm_ctchain_t *
ivm_ctchain_new()
{
	ivm_ctchain_t *ret = MEM_ALLOC(sizeof(*ret));

	IVM_ASSERT(ret, IVM_ERROR_MSG_FAILED_ALLOC_NEW("context chain"));

	ret->head = ret->tail = IVM_NULL;

	return ret;
}

void
ivm_ctchain_free(ivm_ctchain_t *chain)
{
	ivm_ctchain_sub_t *i, *tmp;

	if (chain) {
		for (i = chain->head; i;) {
			tmp = i;
			i = i->inner;
			ivm_ctchain_sub_free(tmp);
		}
		MEM_FREE(chain);
	}

	return;
}

void
ivm_ctchain_addContext(ivm_ctchain_t *chain,
					   ivm_context_t *ct)
{
	ivm_ctchain_sub_t *n_sub = ivm_ctchain_sub_new(ct);

	if (!chain->tail) {
		chain->head = chain->tail = n_sub;
	} else {
		chain->tail->inner = n_sub;
		n_sub->outer = chain->tail;
		chain->tail = n_sub;
	}

	return;
}

void
ivm_ctchain_removeContext(ivm_ctchain_t *chain,
						  ivm_context_t *ct)
{
	ivm_ctchain_sub_t *i;

	RFOREACH (i, chain) {
		if (i->ct == ct) {
			if (i->outer)
				i->outer->inner = i->inner;

			if (i->inner)
				i->inner->outer = i->outer;

			if (i == chain->head)
				chain->head = i->inner;

			if (i == chain->tail)
				chain->tail = i->outer;

			ivm_ctchain_sub_free(i);

			break;
		}
	}

	return;
}

ivm_object_t *
ivm_ctchain_search(ivm_ctchain_t *chain,
				   struct ivm_vmstate_t_tag *state,
				   const ivm_char_t *key)
{
	ivm_slot_t *slot = ivm_ctchain_searchSlot(chain, state, key);

	return slot ? ivm_slot_getValue(slot, state) : IVM_NULL;
}

ivm_slot_t *
ivm_ctchain_searchSlot(ivm_ctchain_t *chain,
					   struct ivm_vmstate_t_tag *state,
					   const ivm_char_t *key)
{
	ivm_slot_t *slot = IVM_NULL;
	ivm_ctchain_sub_t *i;

	RFOREACH (i, chain) {
		slot = ivm_object_getSlot(GET_CONTEXT(i), state, key);
		if (slot && ivm_slot_getValue(slot, state))
			return slot;
	}

	return IVM_NULL;
}

ivm_ctchain_t *
ivm_ctchain_clone(ivm_ctchain_t *chain)
{
	ivm_ctchain_t *ret;
	ivm_ctchain_sub_t *i;

	if (!chain)
		return IVM_NULL;

	ret = ivm_ctchain_new();

	FOREACH (i, chain) {
		ivm_ctchain_addContext(ret, GET_CONTEXT(i));
	}

	return ret;
}

void
ivm_ctchain_foreach(ivm_ctchain_t *chain,
					ivm_ctchain_foreach_proc_t proc,
{'fraction_non_alphanumeric': 0.14255205552589428, 'fraction_numerical': 0.001601708489054992, 'mean_word_length': 4.306893295561851, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 73, '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': '7408821', 'n_tokens_mistral': 2731, 'n_tokens_neox': 2518, 'n_words': 436}