<commit_before>#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include "classifier.h"
#include "freesasa_internal.h"

/**
    In this file the concept class refers to polar/apolar and type to
    aliphatic/aromatic/etc. See the example configurations in share/.
 */

static const struct classifier_types empty_types = {0, 0, NULL, NULL, NULL, NULL};

static const struct classifier_residue empty_residue = {0, NULL, NULL, NULL, NULL, {NULL, 0, 0, 0, 0, 0}};

static const struct freesasa_classifier empty_config = {0, 0, NULL, NULL, NULL, NULL, NULL};

static struct classifier_types*
classifier_types_new()
{
    struct classifier_types *t = malloc(sizeof(struct classifier_types));
    if (t == NULL) {
        mem_fail();
        return NULL;
    }
    *t = empty_types;
    return t;
}

static void
classifier_types_free(struct classifier_types* t)
{
    if (t == NULL) return;
    free(t->type_radius);
    free(t->type_class);

    if (t->name)
        for (int i = 0; i < t->n_types; ++i)
            free(t->name[i]);
    free(t->name);

    if (t->class_name)
        for (int i = 0; i < t->n_classes; ++i)
            free(t->class_name[i]);
    free(t->class_name);

    free(t);
}

static struct classifier_residue*
classifier_residue_new(const char* name)
{
    assert(strlen(name) > 0);
    struct classifier_residue *res = malloc(sizeof(struct classifier_residue));
    if (res == NULL) {
        mem_fail();
        return NULL;
    }
    *res = empty_residue;
    res->name = strdup(name);
    if (res->name == NULL) {
        mem_fail();
        free(res);
        return NULL;
    }
    return res;
}

static void
classifier_residue_free(struct classifier_residue* res)
{
    if (res == NULL) return;
    free(res->name);

    if (res->atom_name)
        for (int i = 0; i < res->n_atoms; ++i)
            free(res->atom_name[i]);
    free(res->atom_name);

    free(res->atom_radius);
    free(res->atom_class);

    free(res);
}

// Not tested!
static struct classifier_residue*
classifier_residue_clone(const struct classifier_residue *residue)
{
    struct classifier_residue *clone = classifier_residue_new(residue->name);

    if (!clone) {
        fail_msg("");
        return NULL;
    }
    clone->n_atoms = residue->n_atoms;
    clone->max_area = residue->max_area;
    clone->atom_name = malloc(clone->n_atoms * sizeof(char*));
    clone->atom_radius = malloc(clone->n_atoms * sizeof(double));
    clone->atom_class = malloc(clone->n_atoms * sizeof(int));
    if (!clone->atom_name || !clone->atom_radius || !clone->atom_class) {
        goto memerr;
    }
    
    for (int i = 0; i < clone->n_atoms; ++i) clone->atom_name[i] = NULL;
    for (int i = 0; i < clone->n_atoms; ++i) {
        clone->atom_name[i] = strdup(residue->atom_name[i]);
        if (!clone->atom_name[i]) goto memerr;
    }

    memcpy(clone->atom_radius, residue->atom_radius, sizeof(double)*clone->n_atoms);
    memcpy(clone->atom_class, residue->atom_class, sizeof(int)*clone->n_atoms);
    
    return clone;
 memerr:
    mem_fail();
    classifier_residue_free(clone);
    return NULL;
}



static freesasa_classifier* 
freesasa_classifier_new()
{
    struct freesasa_classifier *cfg = malloc(sizeof(struct freesasa_classifier));
    if (cfg == NULL) {
        mem_fail();
        return NULL;
    }
    *cfg = empty_config;
    return cfg;
}

// Not tested!!
freesasa_classifier *
freesasa_classifier_clone(const freesasa_classifier *classifier)
{
    freesasa_classifier *clone = freesasa_classifier_new();

    if (!clone) {
        fail_msg("");
        return NULL;
    }
    memcpy(clone, classifier, sizeof(freesasa_classifier)); 
    clone->residue_name = malloc(clone->n_residues*sizeof(char*));
    clone->residue = malloc(clone->n_residues*sizeof(struct classifier_residue*));
    clone->class_name = malloc(clone->n_classes*sizeof(char*));
    clone->name = strdup(classifier->name);
    
    if (!clone->residue_name || !clone->residue ||
        !clone->class_name || !clone->name)
        goto memerr;
    for (int i = 0; i < clone->n_residues; ++i) {
        clone->residue_name[i] = NULL;
        clone->class_name[i] = NULL;
        clone->residue[i] = NULL;
    }
    for (int i = 0; i < clone->n_residues; ++i) {
        clone->residue_name[i] = strdup(classifier->residue_name[i]);
        clone->class_name[i] = strdup(classifier->class_name[i]);
        clone->residue[i] = classifier_residue_clone(classifier->residue[i]);
        if (!clone->residue_name[i] || !clone->class_name[i] || clone->residue[i])
            goto memerr;
    }
    
    return clone;

 memerr:
    mem_fail();
    freesasa_classifier_free(clone);
    return NULL;
}

void
freesasa_classifier_free(freesasa_classifier *c)
{
    if (c == NULL) return;

    if (c->class_name)
        for (int i = 0; i < c->n_classes; ++i)
            free(c->class_name[i]);
    free(c->class_name);

    if (c->residue)
        for (int i = 0; i < c->n_residues; ++i)
            classifier_residue_free(c->residue[i]);
    free(c->residue);
    free(c->residue_name);

    free(c);
}

//! check if array of strings has a string that matches key, ignores trailing and leading whitespace
static int <commit_msg>Remove unused code<commit_after>#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include "classifier.h"
#include "freesasa_internal.h"

/**
    In this file the concept class refers to polar/apolar and type to
    aliphatic/aromatic/etc. See the example configurations in share/.
 */

static const struct classifier_types empty_types = {0, 0, NULL, NULL, NULL, NULL};

static const struct classifier_residue empty_residue = {0, NULL, NULL, NULL, NULL, {NULL, 0, 0, 0, 0, 0}};

static const struct freesasa_classifier empty_config = {0, 0, NULL, NULL, NULL, NULL, NULL};

static struct classifier_types*
classifier_types_new()
{
    struct classifier_types *t = malloc(sizeof(struct classifier_types));
    if (t == NULL) {
        mem_fail();
        return NULL;
    }
    *t = empty_types;
    return t;
}

static void
classifier_types_free(struct classifier_types* t)
{
    if (t == NULL) return;
    free(t->type_radius);
    free(t->type_class);

    if (t->name)
        for (int i = 0; i < t->n_types; ++i)
            free(t->name[i]);
    free(t->name);

    if (t->class_name)
        for (int i = 0; i < t->n_classes; ++i)
            free(t->class_name[i]);
    free(t->class_name);

    free(t);
}

static struct classifier_residue*
classifier_residue_new(const char* name)
{
    assert(strlen(name) > 0);
    struct classifier_residue *res = malloc(sizeof(struct classifier_residue));
    if (res == NULL) {
        mem_fail();
        return NULL;
    }
    *res = empty_residue;
    res->name = strdup(name);
    if (res->name == NULL) {
        mem_fail();
        free(res);
        return NULL;
    }
    return res;
}

static void
classifier_residue_free(struct classifier_residue* res)
{
    if (res == NULL) return;
    free(res->name);

    if (res->atom_name)
        for (int i = 0; i < res->n_atoms; ++i)
            free(res->atom_name[i]);
    free(res->atom_name);

    free(res->atom_radius);
    free(res->atom_class);

    free(res);
}

static freesasa_classifier* 
freesasa_classifier_new()
{
    struct freesasa_classifier *cfg = malloc(sizeof(struct freesasa_classifier));
    if (cfg == NULL) {
        mem_fail();
        return NULL;
    }
    *cfg = empty_config;
    return cfg;
}

void
freesasa_classifier_free(freesasa_classifier *c)
{
    if (c == NULL) return;

    if (c->class_name)
        for (int i = 0; i < c->n_classes; ++i)
            free(c->class_name[i]);
    free(c->class_name);

    if (c->residue)
        for (int i = 0; i < c->n_residues; ++i)
            classifier_residue_free(c->residue[i]);
    free(c->residue);
    free(c->residue_name);

    free(c);
}

//! check if array of strings has a string that matches key, ignores trailing and leading whitespace
static int 
{'fraction_non_alphanumeric': 0.14343707713125844, 'fraction_numerical': 0.004428589002337311, 'mean_word_length': 3.048804780876494, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 125, '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': '2922401', 'n_tokens_mistral': 2984, 'n_tokens_neox': 2820, 'n_words': 652}