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

#include <disir/disir.h>

#include "config.h"
#include "context_private.h"
#include "documentation.h"
#include "keyval.h"
#include "log.h"
#include "mold.h"
#include "multimap.h"
#include "restriction.h"
#include "section.h"

//! Forward declare
static enum disir_status
diff_compare_contexts_with_report (struct disir_context *lhs, struct disir_context *rhs,
                                   struct disir_diff_report *report);


// String hashing function for the multimap
// http://www.cse.yorku.ca/~oz/hash.html
static unsigned long djb2 (char *str)
{
    unsigned long hash = 5381;
    char c;
    while( (c = *str++) ) {
        hash = ((hash << 5) + hash) + c;
    }
    return hash;
}

//! STATIC FUNCTION
static struct disir_diff_report *
dx_diff_report_create (void)
{
    struct disir_diff_report *report;

    report = calloc(1, sizeof (struct disir_diff_report));
    if (report == NULL)
        goto error;

    report->dr_internal_allocated = 20;
    report->dr_entries = 0;

    report->dr_diff_string = calloc (report->dr_internal_allocated, sizeof (char **));
    if (report->dr_diff_string == NULL)
        goto error;

    return report;
error:
    if (report->dr_diff_string)
        free (report->dr_diff_string);
    if (report)
        free (report);

    return NULL;
}

//! STATIC FUNCTION
static void
dx_diff_report_destroy (struct disir_diff_report **report)
{
    int i = 0;

    for (i = 0; i < (*report)->dr_entries; i++)
    {
        free ((*report)->dr_diff_string[i]);
    }
    free ((*report)->dr_diff_string);
    free (*report);
    *report = NULL;
}

//! STATIC FUNCTION
static void
dx_diff_report_add (struct disir_diff_report *report, const char *fmt, ...)
{
    va_list args;
    int i;
    int n = 128;
    int ret = 0;
    void *moved = NULL;

    if (report->dr_entries == report->dr_internal_allocated)
    {
        moved = realloc (report->dr_diff_string,
                         (report->dr_internal_allocated * 2) * sizeof (char **));
        if (moved != NULL)
        {
            report->dr_diff_string = moved;
            report->dr_internal_allocated *= 2;
        }
        else
        {
            log_error ("Failed to reallocate memory for diff report entry.");
            return;
        }
    }

    i = report->dr_entries;
    report->dr_diff_string[i] = malloc (n);
    if (report->dr_diff_string[i] == NULL)
    {
        log_error ("Failed to allocate memory for diff entry string.");
        return;
    }

    va_start (args, fmt);
    do
    {
        ret = vsnprintf (report->dr_diff_string[i], n, fmt, args);
        if (ret < 0)
        {
            // Encoding error.
            log_error ("vsnprintf encoding error. Failed to write diff report string.");
            break;
        }
        else if (ret >= n)
        {
            // Insufficient space.
            n *= 2;
            moved = realloc (report->dr_diff_string, n);
            if (moved)
            {
                report->dr_diff_string[i] = moved;
            }
            else<commit_msg>fix lib: Fix dx_diff_report_add string buffer realloc<commit_after>#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#include <disir/disir.h>

#include "config.h"
#include "context_private.h"
#include "documentation.h"
#include "keyval.h"
#include "log.h"
#include "mold.h"
#include "multimap.h"
#include "restriction.h"
#include "section.h"

//! Forward declare
static enum disir_status
diff_compare_contexts_with_report (struct disir_context *lhs, struct disir_context *rhs,
                                   struct disir_diff_report *report);


// String hashing function for the multimap
// http://www.cse.yorku.ca/~oz/hash.html
static unsigned long djb2 (char *str)
{
    unsigned long hash = 5381;
    char c;
    while( (c = *str++) ) {
        hash = ((hash << 5) + hash) + c;
    }
    return hash;
}

//! STATIC FUNCTION
static struct disir_diff_report *
dx_diff_report_create (void)
{
    struct disir_diff_report *report;

    report = calloc(1, sizeof (struct disir_diff_report));
    if (report == NULL)
        goto error;

    report->dr_internal_allocated = 20;
    report->dr_entries = 0;

    report->dr_diff_string = calloc (report->dr_internal_allocated, sizeof (char **));
    if (report->dr_diff_string == NULL)
        goto error;

    return report;
error:
    if (report->dr_diff_string)
        free (report->dr_diff_string);
    if (report)
        free (report);

    return NULL;
}

//! STATIC FUNCTION
static void
dx_diff_report_destroy (struct disir_diff_report **report)
{
    int i = 0;

    for (i = 0; i < (*report)->dr_entries; i++)
    {
        free ((*report)->dr_diff_string[i]);
    }
    free ((*report)->dr_diff_string);
    free (*report);
    *report = NULL;
}

//! STATIC FUNCTION
static void
dx_diff_report_add (struct disir_diff_report *report, const char *fmt, ...)
{
    va_list args;
    int i;
    int n = 128;
    int ret = 0;
    void *moved = NULL;

    if (report->dr_entries == report->dr_internal_allocated)
    {
        moved = realloc (report->dr_diff_string,
                         (report->dr_internal_allocated * 2) * sizeof (char **));
        if (moved != NULL)
        {
            report->dr_diff_string = moved;
            report->dr_internal_allocated *= 2;
        }
        else
        {
            log_error ("Failed to reallocate memory for diff report entry.");
            return;
        }
    }

    i = report->dr_entries;
    report->dr_diff_string[i] = malloc (n);
    if (report->dr_diff_string[i] == NULL)
    {
        log_error ("Failed to allocate memory for diff entry string.");
        return;
    }

    va_start (args, fmt);
    do
    {
        va_list args_copy;
        va_copy (args_copy, args);
        ret = vsnprintf (report->dr_diff_string[i], n, fmt, args_copy);
        va_end (args_copy);
        if (ret < 0)
        {
            // Encoding error.
            log_error ("vsnprintf encoding error. Failed to write diff report string.");
            break;
        }
        else if (ret >= n)
        {
            // Insufficient space.
            n = ret + sizeof ('\0');
            moved = realloc (report->dr_diff_string[i], n);
            if (moved)
            {
                report->dr_diff_string[i] = moved;
            }
            else
{'fraction_non_alphanumeric': 0.12490290508000622, 'fraction_numerical': 0.006214074879602299, 'mean_word_length': 2.2029850746268655, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2793223', 'n_tokens_mistral': 2166, 'n_tokens_neox': 2080, 'n_words': 528}