<commit_before>/*
Copyright (C) 2001-2008, The Perl Foundation.
$Id$

=head1 NAME

src/io.c - Common I/O utility functions

=head1 DESCRIPTION

This file defines a set of utility functions for I/O operations used by all
operating systems. For the primary public I/O API, see F<src/io/api.c>.

=cut

*/

#include "parrot/parrot.h"
#include "io/io_private.h"
#include "pmc/pmc_filehandle.h"

/* HEADERIZER HFILE: include/parrot/io.h */

/*

=head2 Functions

=over 4

=item C<INTVAL Parrot_io_parse_open_flags>

Parses a Parrot string for file open mode flags (C<r> for read, C<w> for write,
C<a> for append, and C<p> for pipe) and returns the combined generic bit flags.

=cut

*/

PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
INTVAL
Parrot_io_parse_open_flags(PARROT_INTERP, ARGIN_NULLOK(STRING *mode_str))
{
    INTVAL i, mode_len;
    INTVAL flags = 0;

    if (STRING_IS_NULL(mode_str))
        return PIO_F_READ;

    mode_len = string_length(interp, mode_str);

    for (i = 0; i < mode_len; ++i) {
        INTVAL s = string_index(interp, mode_str, i);
        switch (s) {
            case 'r':
                flags |= PIO_F_READ;
                break;
            case 'w':
                flags |= PIO_F_WRITE;
                if (!(flags & PIO_F_APPEND)) /* don't truncate if appending */
                    flags |= PIO_F_TRUNC;
                break;
            case 'a':
                flags |= PIO_F_APPEND;
                if ((flags & PIO_F_TRUNC)) /* don't truncate if appending */
                    flags &= ~PIO_F_TRUNC;
                break;
            case 'p':
                flags |= PIO_F_PIPE;
                break;
            default:
                break;
        }
    }

    /* These comparisons are put in place for backward compatibility, and will
     * be removed after a deprecation cycle. */
    if (flags == 0) {
        INTVAL first = string_index(interp, mode_str, 0);
        INTVAL second = string_index(interp, mode_str, 1);
        switch (first) {
            case '+':
                flags |= (PIO_F_WRITE | PIO_F_READ);
                switch (second) {
                    case '<':
                        break;
                    case '>':
                        flags |= PIO_F_TRUNC;
                        break;
                    default:
                        return 0;
                }
                break;
            case '<':
                flags |= PIO_F_READ;
                break;
            case '>':
                flags |= PIO_F_WRITE;
                if (second == '>') {
                    flags |= PIO_F_APPEND;
                }
                else {
                    flags |= PIO_F_TRUNC;
                }
                break;
            case '-':       /* -| read from pipe */
                if (second == '|') {
                    flags |= PIO_F_PIPE | PIO_F_READ;
                }
                break;
            case '|':       /* |- write to pipe */
                if (second == '-') {
                    flags |= PIO_F_PIPE | PIO_F_WRITE;
                }
                break;
            default:
                return 0;
        }
    }

    return flags;
}

/*

=item C<STRING * Parrot_io_make_string>

Creates a STRING* suitable for returning results from IO read functions.
The passed in C<buf> parameter can:

=over 4

=item 1

Point to a NULL STRING

=item 2

Point to a real STRING

=item 3

Point to a fake STRING with (strstart, bufused) holding the *buffer
information.

=back

In the third case, the buffer or STRING must be able to hold the required
amount of data. For cases 1 and 2, a NULL C<strstart> tells this function to
allocate the STRING memory.

=cut

*/

PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
STRING *
Parrot_io_make_string(PARROT_INTERP, ARGMOD(STRING **buf), size_t len)
{
    /*
     * when we get a NULL string, we read a default len
     */
    if (*buf == NULL) {
        *buf = string_make_empty(interp, enum_stringrep_one, len);
        return *buf;
    }
    else {
        STRING *s = *buf;
        if (s->bufused < len)
            Parrot_allocate_string(interp, s, len);
        return s;
    }
}<commit_msg>[IO] When extending a STRING's buffer in Parrot_io_make_string(), use Parrot_reallocate_string() instead of Parrot_allocate_string(), so as not to lose existing contents of the buffer.  See TT #52, filed by <NAME>.<commit_after>/*
Copyright (C) 2001-2008, The Perl Foundation.
$Id$

=head1 NAME

src/io.c - Common I/O utility functions

=head1 DESCRIPTION

This file defines a set of utility functions for I/O operations used by all
operating systems. For the primary public I/O API, see F<src/io/api.c>.

=cut

*/

#include "parrot/parrot.h"
#include "io/io_private.h"
#include "pmc/pmc_filehandle.h"

/* HEADERIZER HFILE: include/parrot/io.h */

/*

=head2 Functions

=over 4

=item C<INTVAL Parrot_io_parse_open_flags>

Parses a Parrot string for file open mode flags (C<r> for read, C<w> for write,
C<a> for append, and C<p> for pipe) and returns the combined generic bit flags.

=cut

*/

PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
INTVAL
Parrot_io_parse_open_flags(PARROT_INTERP, ARGIN_NULLOK(STRING *mode_str))
{
    INTVAL i, mode_len;
    INTVAL flags = 0;

    if (STRING_IS_NULL(mode_str))
        return PIO_F_READ;

    mode_len = string_length(interp, mode_str);

    for (i = 0; i < mode_len; ++i) {
        INTVAL s = string_index(interp, mode_str, i);
        switch (s) {
            case 'r':
                flags |= PIO_F_READ;
                break;
            case 'w':
                flags |= PIO_F_WRITE;
                if (!(flags & PIO_F_APPEND)) /* don't truncate if appending */
                    flags |= PIO_F_TRUNC;
                break;
            case 'a':
                flags |= PIO_F_APPEND;
                if ((flags & PIO_F_TRUNC)) /* don't truncate if appending */
                    flags &= ~PIO_F_TRUNC;
                break;
            case 'p':
                flags |= PIO_F_PIPE;
                break;
            default:
                break;
        }
    }

    /* These comparisons are put in place for backward compatibility, and will
     * be removed after a deprecation cycle. */
    if (flags == 0) {
        INTVAL first = string_index(interp, mode_str, 0);
        INTVAL second = string_index(interp, mode_str, 1);
        switch (first) {
            case '+':
                flags |= (PIO_F_WRITE | PIO_F_READ);
                switch (second) {
                    case '<':
                        break;
                    case '>':
                        flags |= PIO_F_TRUNC;
                        break;
                    default:
                        return 0;
                }
                break;
            case '<':
                flags |= PIO_F_READ;
                break;
            case '>':
                flags |= PIO_F_WRITE;
                if (second == '>') {
                    flags |= PIO_F_APPEND;
                }
                else {
                    flags |= PIO_F_TRUNC;
                }
                break;
            case '-':       /* -| read from pipe */
                if (second == '|') {
                    flags |= PIO_F_PIPE | PIO_F_READ;
                }
                break;
            case '|':       /* |- write to pipe */
                if (second == '-') {
                    flags |= PIO_F_PIPE | PIO_F_WRITE;
                }
                break;
            default:
                return 0;
        }
    }

    return flags;
}

/*

=item C<STRING * Parrot_io_make_string>

Creates a STRING* suitable for returning results from IO read functions.
The passed in C<buf> parameter can:

=over 4

=item 1

Point to a NULL STRING

=item 2

Point to a real STRING

=item 3

Point to a fake STRING with (strstart, bufused) holding the *buffer
information.

=back

In the third case, the buffer or STRING must be able to hold the required
amount of data. For cases 1 and 2, a NULL C<strstart> tells this function to
allocate the STRING memory.

=cut

*/

PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
STRING *
Parrot_io_make_string(PARROT_INTERP, ARGMOD(STRING **buf), size_t len)
{
    /* when we get a NULL string, we read a default len */
    if (*buf == NULL) {
        *buf = string_make_empty(interp, enum_stringrep_one, len);
        return *buf;
    }
    else {
        STRING *s = *buf;
        if (s->bufused < len)
            Parrot_reallocate_string(interp, s, len);
        return s;
    }
}
{'fraction_non_alphanumeric': 0.09577332865004098, 'fraction_numerical': 0.0060882800608828, 'mean_word_length': 1.5736667670985236, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 30, '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': '6007978', 'n_tokens_mistral': 2793, 'n_tokens_neox': 2617, 'n_words': 776}