<commit_before>/*-----------------------------------------------------------------------------
 *
 * node.c
 *		Basic functions for nodes.
 *		
 *		AUTHOR: lord_pretzel
 *
 *		Right now only implements node creation.
 *
 *-----------------------------------------------------------------------------
 */

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

#include "log/logger.h"
#include "mem_manager/mem_mgr.h"
#include "model/node/nodetype.h"

#define INITIAL_STRINGINFO_LENGTH 256

/* function declarations */
static void makeStringInfoSpace (StringInfo str, int needs);

/*
 * Create a new node of a certain type.
 */
Node *
newNode(size_t size, NodeTag type)
{
    Node *newNode;

    newNode = (Node *) MALLOC(size);
    newNode->type = type;

    return newNode;
}

/*
 * Create a new StringInfo.
 */
StringInfo
makeStringInfo(void)
{
    StringInfo result = NEW(StringInfoData);
    initStringInfo(result);

    return result;
}

/*
 * The function initializes a StringInfoData.
 */
void
initStringInfo(StringInfo str)
{
    str->cursor = 0;
    str->len = 0;
    str->maxlen = INITIAL_STRINGINFO_LENGTH;
    str->data = (char *) MALLOC(INITIAL_STRINGINFO_LENGTH);
}

/*
 *The function is clear the current content of StringInfo.
 */
void
resetStringInfo(StringInfo str)
{
    str->cursor = 0;
    memset(str->data, 0, str->len);
    str->len = 0;
}

void
appendStringInfoChar(StringInfo str, const char c)
{
    makeStringInfoSpace(str, 1);

    str->data[str->len] = c;
    str->len++;
    str->data[str->len] = '\0';
}

/*------------------------------------------------------------------
*appendStringInfoString
*The function is append a string to str.
*-------------------------------------------------------------------*/
void
appendStringInfoString(StringInfo str, const char *s)
{
    makeStringInfoSpace(str, strlen(s));

    // copy s including final '\0' starting after last char of str
    memcpy(str->data + str->len, s, strlen(s) + 1);
    str->len += strlen(s);
}


void
appendStringInfo(StringInfo str, const char *format, ...)
{
    for(;;)
    {
        va_list     args;
        int needed, have;

        have = str->maxlen - str->len - 1;
        va_start(args, format);
        needed = vsnprintf(str->data + str->len, have, format, args);
        va_end(args);

        if (needed >= 0 && needed < have - 1)
        {
            str->len += needed;
            break;
        }

        makeStringInfoSpace(str, needed);
    }
}


/*
 * Make sure that a string info has enough space to be enlarged by additonal
 * neededSize char's.<commit_msg>fixed error in appendStringInfo that causes infinite loop if string info is enlarged in the process<commit_after>/*-----------------------------------------------------------------------------
 *
 * node.c
 *		Basic functions for nodes.
 *		
 *		AUTHOR: lord_pretzel
 *
 *		Right now only implements node creation.
 *
 *-----------------------------------------------------------------------------
 */

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

#include "log/logger.h"
#include "mem_manager/mem_mgr.h"
#include "model/node/nodetype.h"

#define INITIAL_STRINGINFO_LENGTH 256

/* function declarations */
static void makeStringInfoSpace (StringInfo str, int needs);

/*
 * Create a new node of a certain type.
 */
Node *
newNode(size_t size, NodeTag type)
{
    Node *newNode;

    newNode = (Node *) MALLOC(size);
    newNode->type = type;

    return newNode;
}

/*
 * Create a new StringInfo.
 */
StringInfo
makeStringInfo(void)
{
    StringInfo result = NEW(StringInfoData);
    initStringInfo(result);

    return result;
}

/*
 * The function initializes a StringInfoData.
 */
void
initStringInfo(StringInfo str)
{
    str->cursor = 0;
    str->len = 0;
    str->maxlen = INITIAL_STRINGINFO_LENGTH;
    str->data = (char *) MALLOC(INITIAL_STRINGINFO_LENGTH);
}

/*
 *The function is clear the current content of StringInfo.
 */
void
resetStringInfo(StringInfo str)
{
    str->cursor = 0;
    memset(str->data, 0, str->len);
    str->len = 0;
}

void
appendStringInfoChar(StringInfo str, const char c)
{
    makeStringInfoSpace(str, 1);

    str->data[str->len] = c;
    str->len++;
    str->data[str->len] = '\0';
}

/*------------------------------------------------------------------
*appendStringInfoString
*The function is append a string to str.
*-------------------------------------------------------------------*/
void
appendStringInfoString(StringInfo str, const char *s)
{
    makeStringInfoSpace(str, strlen(s));

    // copy s including final '\0' starting after last char of str
    memcpy(str->data + str->len, s, strlen(s) + 1);
    str->len += strlen(s);
}


void
appendStringInfo(StringInfo str, const char *format, ...)
{
    for(;;)
    {
        va_list     args;
        int needed, have;

        have = str->maxlen - str->len - 1;
        va_start(args, format);
        needed = vsnprintf(str->data + str->len, have, format, args);
        va_end(args);

        if (needed >= 0 && needed <= have)
        {
            str->len += needed;
            break;
        }
        if (needed < 0)
            FATAL_LOG("encoding error in appendStringInfo <%s>", format);

        makeStringInfoSpace(str, needed);
    }
}


/*
 * Make sure that a string info has enough space to be enlarged by additonal
 * neededSize char's.
{'fraction_non_alphanumeric': 0.22510822510822512, 'fraction_numerical': 0.00564652738565782, 'mean_word_length': 1.9246009906439185, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 54, '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': '4904631', 'n_tokens_mistral': 1638, 'n_tokens_neox': 1572, 'n_words': 434}