<commit_before>
#include "parrot/parrot.h"

#include "binary.h"
#include <stdio.h>

static int class_TclFloat  = 0;
static int class_TclInt    = 0;
static int class_TclList   = 0;
static int class_TclString = 0;

/* extract_int
 *
 * Extract an integer from the string at the position given. Return the integer
 * and update the position. Returns 1 if no digit is found or if the int is
 * zero.
 */
static int
extract_int(char *str, int *pos, int length)
{
    int n = 0;

    while (*pos < length && isdigit(str[*pos]))
        n = 10*n + (str[(*pos)++] - '0');

    if (!n)
        n = 1;

    return n;
}

/* binary_scan_number_field
 *
 * Scan and remove a number from a binary string. Return a PMC representing
 * that value.
 */
static PMC *
binary_scan_number_field(Interp *interp, char field, char *binstr, int *_pos, int length)
{
    char *c;
    double *d;
    float *f;
    int *n;

    int len;
    PMC *value = PMCNULL;
    int pos = *_pos;
    switch (field)
    {
        /* a char */
        case 'c':
            if (pos >= length)
                break;
            c     = (char *)(binstr + pos);
            value = pmc_new(interp, class_TclInt);
            VTABLE_set_integer_native(interp, value, (INTVAL)*c);
            pos += 1;
            break;
        /* a double */
        case 'd':
            len = sizeof(double)/sizeof(char);
            if (pos + len > length)
                break;
            d     = (double *)(binstr + pos);
            value = pmc_new(interp, class_TclFloat);
            VTABLE_set_number_native(interp, value, *d);
            pos += len;
            break;
        /* a float */
        case 'f':
            len = sizeof(float)/sizeof(char);
            if (pos + len > length)
                break;
            f     = (float *)(binstr + pos);
            value = pmc_new(interp, class_TclFloat);
            VTABLE_set_number_native(interp, value, *f);
            pos += len;
            break;
        /* a native int */
        case 'n':
            len = sizeof(int)/sizeof(char);
            if (pos + len > length)
                break;
            n     = (int *)(binstr + pos);
            value = pmc_new(interp, class_TclInt);
            VTABLE_set_integer_native(interp, value, *n);
            pos += len;
            break;
    }
    (*_pos) = pos;
    return value;
}

/* binary_scan_number_slurpy
 *
 * Scan the binary string for all remaining occurences of a number of the type
 * of the field. Returns a TclList PMC of the number PMCs.
 */
static PMC *
binary_scan_number_slurpy(Interp *interp, char field, char *binstr, int *_pos, int length)
{
    PMC *elem;
    PMC *values = pmc_new(interp, class_TclList);

    while ((elem = binary_scan_number_field(interp, field, binstr, _pos, length)) != PMCNULL)
        VTABLE_push_pmc(interp, values, elem);

    return values;
}

/* binary_scan_number
 *
 * Scan the binary string for a number field. There may be a width following
 * the field specifier.
 */
static PMC *
binary_scan_number(Interp *interp, char field,
                   char *format, int *formatpos, int formatlen,
                   char *binstr, int *binstrpos, int binstrlen)
{
    PMC *value;

    if ((*formatpos) < formatlen && format[*formatpos] == '*')<commit_msg>[tcl]: Use NULL instead of PMCNULL in src/binary.c<commit_after>
#include "parrot/parrot.h"

#include "binary.h"
#include <stdio.h>

static int class_TclFloat  = 0;
static int class_TclInt    = 0;
static int class_TclList   = 0;
static int class_TclString = 0;

/* extract_int
 *
 * Extract an integer from the string at the position given. Return the integer
 * and update the position. Returns 1 if no digit is found or if the int is
 * zero.
 */
static int
extract_int(char *str, int *pos, int length)
{
    int n = 0;

    while (*pos < length && isdigit(str[*pos]))
        n = 10*n + (str[(*pos)++] - '0');

    if (!n)
        n = 1;

    return n;
}

/* binary_scan_number_field
 *
 * Scan and remove a number from a binary string. Return a PMC representing
 * that value.
 */
static PMC *
binary_scan_number_field(Interp *interp, char field, char *binstr, int *_pos, int length)
{
    char *c;
    double *d;
    float *f;
    int *n;

    int len;
    PMC *value = NULL;
    int pos = *_pos;
    switch (field)
    {
        /* a char */
        case 'c':
            if (pos >= length)
                break;
            c     = (char *)(binstr + pos);
            value = pmc_new(interp, class_TclInt);
            VTABLE_set_integer_native(interp, value, (INTVAL)*c);
            pos += 1;
            break;
        /* a double */
        case 'd':
            len = sizeof(double)/sizeof(char);
            if (pos + len > length)
                break;
            d     = (double *)(binstr + pos);
            value = pmc_new(interp, class_TclFloat);
            VTABLE_set_number_native(interp, value, *d);
            pos += len;
            break;
        /* a float */
        case 'f':
            len = sizeof(float)/sizeof(char);
            if (pos + len > length)
                break;
            f     = (float *)(binstr + pos);
            value = pmc_new(interp, class_TclFloat);
            VTABLE_set_number_native(interp, value, *f);
            pos += len;
            break;
        /* a native int */
        case 'n':
            len = sizeof(int)/sizeof(char);
            if (pos + len > length)
                break;
            n     = (int *)(binstr + pos);
            value = pmc_new(interp, class_TclInt);
            VTABLE_set_integer_native(interp, value, *n);
            pos += len;
            break;
    }
    (*_pos) = pos;
    return value;
}

/* binary_scan_number_slurpy
 *
 * Scan the binary string for all remaining occurences of a number of the type
 * of the field. Returns a TclList PMC of the number PMCs.
 */
static PMC *
binary_scan_number_slurpy(Interp *interp, char field, char *binstr, int *_pos, int length)
{
    PMC *elem;
    PMC *values = pmc_new(interp, class_TclList);

    while (elem = binary_scan_number_field(interp, field, binstr, _pos, length))
        VTABLE_push_pmc(interp, values, elem);

    return values;
}

/* binary_scan_number
 *
 * Scan the binary string for a number field. There may be a width following
 * the field specifier.
 */
static PMC *
binary_scan_number(Interp *interp, char field,
                   char *format, int *formatpos, int formatlen,
                   char *binstr, int *binstrpos, int binstrlen)
{
    PMC *value;

    if ((*formatpos) < formatlen && format[*formatpos] == '*')
{'fraction_non_alphanumeric': 0.115203165423832, 'fraction_numerical': 0.003348044437680718, 'mean_word_length': 1.9872727272727273, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, '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': '893229', 'n_tokens_mistral': 2170, 'n_tokens_neox': 2098, 'n_words': 650}