<commit_before>#include "SafeFormatting.h"
#include "Formatting.h"
#include "System/Buffers/Buffer.h"
#include "System/Buffers/ReadBuffer.h"

static int WriteArg(char* buffer, size_t size, TypedArg& arg)
{
    int     ret;
    
    ret = 0;
    
    switch (arg.type)
    {
    case TypedArg::CHAR:
        ret = Writef(buffer, size, "%c", *(char*) arg.pointer);
        break;
    case TypedArg::CHAR_STAR:
        ret = Writef(buffer, size, "%s", (const char*) arg.pointer);
        break;
    case TypedArg::INT32:
        ret = Writef(buffer, size, "%d", *(const int32_t*) arg.pointer);
        break;
    case TypedArg::UINT32:
        ret = Writef(buffer, size, "%u", *(const uint32_t*) arg.pointer);
        break;
    case TypedArg::INT64:
        ret = Writef(buffer, size, "%I", *(const int64_t*) arg.pointer);
        break;
    case TypedArg::UINT64:
        ret = Writef(buffer, size, "%U", *(const uint64_t*) arg.pointer);
        break;
    case TypedArg::FLOAT:
        ret = Writef(buffer, size, "%d", *(const float*) arg.pointer);
        break;
    case TypedArg::DOUBLE:
        ret = Writef(buffer, size, "%ld", *(const double*) arg.pointer);
        break;
    case TypedArg::BUFFER:
        ret = Writef(buffer, size, "%B", (const Buffer*) arg.pointer);
        break;
    case TypedArg::READBUFFER:
        ret = Writef(buffer, size, "%R", (const ReadBuffer*) arg.pointer);
        break;
    }
    
    return ret;
}

int SFWrite(char* buffer, size_t size, const char* fmt, const FormatStack& formatStack)
{
    const char*     f;
    size_t          pos;
    TypedArg        arg;
    int             ret;
    
    f = fmt;

    while (*f)
    {
        // start of a formatted argument
        if (*f == '{')
        {
            pos = f[1] - '0';
            arg = formatStack.args[pos];
            ret = WriteArg(buffer, size, arg);
            buffer += ret;
            size -= ret;
            
            f += 3;
            continue;
        }
        
        *buffer = *f;
        f += 1;
        
        buffer += 1;
        size -= 1;
    }
    
    return 0;
}<commit_msg>Added more edge-case handling to safe formatting code.<commit_after>#include "SafeFormatting.h"
#include "Formatting.h"
#include "System/Buffers/Buffer.h"
#include "System/Buffers/ReadBuffer.h"

static int WriteArg(char* buffer, size_t size, TypedArg& arg)
{
    int     ret;
    
    ret = 0;
    
    switch (arg.type)
    {
    case TypedArg::CHAR:
        ret = Writef(buffer, size, "%c", *(char*) arg.pointer);
        break;
    case TypedArg::CHAR_STAR:
        ret = Writef(buffer, size, "%s", (const char*) arg.pointer);
        break;
    case TypedArg::INT32:
        ret = Writef(buffer, size, "%d", *(const int32_t*) arg.pointer);
        break;
    case TypedArg::UINT32:
        ret = Writef(buffer, size, "%u", *(const uint32_t*) arg.pointer);
        break;
    case TypedArg::INT64:
        ret = Writef(buffer, size, "%I", *(const int64_t*) arg.pointer);
        break;
    case TypedArg::UINT64:
        ret = Writef(buffer, size, "%U", *(const uint64_t*) arg.pointer);
        break;
    case TypedArg::FLOAT:
        ret = Writef(buffer, size, "%d", *(const float*) arg.pointer);
        break;
    case TypedArg::DOUBLE:
        ret = Writef(buffer, size, "%ld", *(const double*) arg.pointer);
        break;
    case TypedArg::BUFFER:
        ret = Writef(buffer, size, "%B", (const Buffer*) arg.pointer);
        break;
    case TypedArg::READBUFFER:
        ret = Writef(buffer, size, "%R", (const ReadBuffer*) arg.pointer);
        break;
    }
    
    return ret;
}

int SFWrite(char* buffer, size_t size, const char* fmt, const FormatStack& formatStack)
{
    const char*     f;
    size_t          pos;
    TypedArg        arg;
    int             ret;
    
    f = fmt;

    // TODO: handle edge cases, buffer overflows etc.
    while (*f)
    {
        // start of a formatted argument
        if (*f == '{')
        {
            if (f[1] == 0 || f[2] == 0)
                return -1;

            pos = f[1] - '0';
            arg = formatStack.args[pos];
            ret = WriteArg(buffer, size, arg);
            buffer += ret;
            size -= ret;
            
            f += 3;
            continue;
        }
        
        *buffer = *f;
        f += 1;
        
        buffer += 1;
        size -= 1;
    }
    
    return 0;
}
{'fraction_non_alphanumeric': 0.14279207469824642, 'fraction_numerical': 0.012070143475290366, 'mean_word_length': 1.8317214700193423, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '3077010', 'n_tokens_mistral': 1458, 'n_tokens_neox': 1418, 'n_words': 381}