<commit_before>/*
 * tree.c - Implementation of tree.
 *
 * Copyright (C) 2014 <NAME>
 *
 * This file released under the AGPLv3.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include "tree.h"
#include "list.h"

/*
 * Initializes tree with reference to parent and data, and an empty
 * (but initialized) list of children.
 */
struct tree *tree_init(struct tree *parent, void *data)
{
	struct tree *t = malloc(sizeof(*t));
	if (t == NULL) {
		perror("tree_init()");
		return NULL;
	}

	struct list *l = list_init();
	if (l == NULL) {
		free(t);
		return NULL;
	}

	t->parent = parent;
	t->data = data;
	t->children = l;

	return t;
}

/*
 * Initializes tree with reference to parent and data, and pushes
 * count number of following struct tree * as children.
 */
struct tree *tree_initv(struct tree *parent, void *data, int count, ...)
{
	va_list ap;
	va_start(ap, count);

	struct tree *t = tree_init(parent, data);

	for (int i = 0; i < count; ++i) {
		struct tree *c = va_arg(ap, void *);
		c->parent = t;
		list_push(t->children, c);
	}

	va_end(ap);
	return t;
}

/*
 * Recursively calculates size of tree.
 */
size_t tree_size(struct tree *self)
{
	if (self == NULL)
		return 0;

	size_t size = 1;

	const struct list_node *iter = list_head(self->children);
	while (!list_end(iter)) {
		size += tree_size((struct tree *)iter->data);
		iter = iter->next;
	}

	return size;
}

/*
 * Pre-order traversal of tree. Takes a function and applies it to
 * each subtree.
 */
void tree_preorder(struct tree *self, int depth, void (*f)(struct tree *t, int d))
{
	if (self == NULL)
		return;
	f(self, depth);
	++depth;
	const struct list_node *iter = list_head(self->children);
	while (!list_end(iter)) {
		tree_preorder(iter->data, depth, f);
		iter = iter->next;
	}
}

/*
 * Initializes a child tree with self as parent and data
 * reference. Pushes the child tree as data to self's list of
 * children. Returns reference to child tree.
 */
struct tree *tree_push(struct tree *self, void *data)
{
	struct tree *child = tree_init(self, data);
	if (child == NULL) {
		perror("tree_push()");
		return NULL;
	}

	list_push(self->children, child);

	return child;
}<commit_msg>More clear depth incrementation in tree preorder traversal<commit_after>/*
 * tree.c - Implementation of tree.
 *
 * Copyright (C) 2014 <NAME>
 *
 * This file released under the AGPLv3.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include "tree.h"
#include "list.h"

/*
 * Initializes tree with reference to parent and data, and an empty
 * (but initialized) list of children.
 */
struct tree *tree_init(struct tree *parent, void *data)
{
	struct tree *t = malloc(sizeof(*t));
	if (t == NULL) {
		perror("tree_init()");
		return NULL;
	}

	struct list *l = list_init();
	if (l == NULL) {
		free(t);
		return NULL;
	}

	t->parent = parent;
	t->data = data;
	t->children = l;

	return t;
}

/*
 * Initializes tree with reference to parent and data, and pushes
 * count number of following struct tree * as children.
 */
struct tree *tree_initv(struct tree *parent, void *data, int count, ...)
{
	va_list ap;
	va_start(ap, count);

	struct tree *t = tree_init(parent, data);

	for (int i = 0; i < count; ++i) {
		struct tree *c = va_arg(ap, void *);
		c->parent = t;
		list_push(t->children, c);
	}

	va_end(ap);
	return t;
}

/*
 * Recursively calculates size of tree.
 */
size_t tree_size(struct tree *self)
{
	if (self == NULL)
		return 0;

	size_t size = 1;

	const struct list_node *iter = list_head(self->children);
	while (!list_end(iter)) {
		size += tree_size((struct tree *)iter->data);
		iter = iter->next;
	}

	return size;
}

/*
 * Pre-order traversal of tree. Takes a function and applies it to
 * each subtree.
 */
void tree_preorder(struct tree *self, int depth, void (*f)(struct tree *t, int d))
{
	if (self == NULL)
		return;
	f(self, depth);
	const struct list_node *iter = list_head(self->children);
	while (!list_end(iter)) {
		tree_preorder(iter->data, depth+1, f);
		iter = iter->next;
	}
}

/*
 * Initializes a child tree with self as parent and data
 * reference. Pushes the child tree as data to self's list of
 * children. Returns reference to child tree.
 */
struct tree *tree_push(struct tree *self, void *data)
{
	struct tree *child = tree_init(self, data);
	if (child == NULL) {
		perror("tree_push()");
		return NULL;
	}

	list_push(self->children, child);

	return child;
}
{'fraction_non_alphanumeric': 0.14763293695310747, 'fraction_numerical': 0.003814224814897913, 'mean_word_length': 3.595876288659794, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 37, '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': '426957', 'n_tokens_mistral': 1670, 'n_tokens_neox': 1584, 'n_words': 522}