<commit_before>#include <stdio.h> /* fopen, fseek, fread, fwrite, FILE */
#include <stdlib.h> /* exit */
#include <string.h> /* strcmp, strncmp */

#define QUIT_EXIT_CODE EXIT_SUCCESS
#define EXPECT_EXIT_CODE EXIT_FAILURE

/***** data structures and manipulation *****/

enum Command {
    /* optionally takes num
     * prints $num bytes
     * $num defaults to 100 if not supplied
     */
    print,
    /* takes num
     * goto line in file
     */
    line,
    /* takes num
     * goto byte in file
     */
    byte,
    /* takes string
     * compares string to current file location
     * exits with code <EXPECT_EXIT_CODE> if string doesn't match
     */
    expect,
    /* takes string
     * writes string to current location in file
     * leaves the cursor positioned after the write
     */
    write,
    /* exists with code <QUIT_EXIT_CODE>
     */
    quit
};

union Argument {
    int num;
    char *str;
};

struct Instruction {
    /* type of command determines dispatch to eval_ function
     * which in turn determines which Argument member to use
     */
    enum Command command;
    union Argument argument;
    /* next Instruction in linked list */
    struct Instruction *next;
};

struct Program {
    /* linked list of Instruction(s) */
    struct Instruction *start;
    /* file program is operating on */
    FILE *file;
    /* program source read into a buffer */
    char *source;
    /* shared buffer (and length) used for reading into */
    char *buf;
    size_t buf_len;
};

struct Instruction *new_instruction(enum Command command){
    struct Instruction *i;

    i = calloc(1, sizeof(struct Instruction));
    if( ! i ){
        puts("new_instruction: call to calloc failed");
        return 0;
    }

    i->command = command;

    return i;
}

/***** internal helpers ******/
/* return a buffer of at least size required_len
 * returns 0 on error
 */
char *get_buffer(struct Program *p, size_t required_len){
    if( !p )
        return 0;

    if( p->buf_len <= required_len )
        return p->buf;

    p->buf_len = required_len;
    p->buf = realloc(p->buf, required_len);

    if( ! p->buf_len ){
        puts("get_buffer: failed to allocate buffer");
        return 0;
    }

    return p->buf;
}

/* return a char* containing data from provided FILE*
 * returns 0 on error
 */
char * slurp(FILE *file){
    return 0; /* FIXME unimplemented */
}


/***** parsing functions *****/

struct Instruction * parse_print(char *source, int *index){
    struct Instruction *i;

    i = new_instruction(print);
    if( ! i ){
        puts("Parse_print: call to new_instruction failed");
        return 0;
    }

    puts("parse_print unimplemented");
    return 0; /* FIXME unimplemented */
}

struct Instruction * parse_byte(char *source, int *index){
    struct Instruction *i;

    i = new_instruction(byte);
    if( ! i ){
        puts("Parse_byte: call to new_instruction failed");
        return 0;
    }<commit_msg>basic slurp function added<commit_after>#include <stdio.h> /* fopen, fseek, fread, fwrite, FILE */
#include <stdlib.h> /* exit */
#include <string.h> /* strcmp, strncmp */

#define QUIT_EXIT_CODE EXIT_SUCCESS
#define EXPECT_EXIT_CODE EXIT_FAILURE

/***** data structures and manipulation *****/

enum Command {
    /* optionally takes num
     * prints $num bytes
     * $num defaults to 100 if not supplied
     */
    print,
    /* takes num
     * goto line in file
     */
    line,
    /* takes num
     * goto byte in file
     */
    byte,
    /* takes string
     * compares string to current file location
     * exits with code <EXPECT_EXIT_CODE> if string doesn't match
     */
    expect,
    /* takes string
     * writes string to current location in file
     * leaves the cursor positioned after the write
     */
    write,
    /* exists with code <QUIT_EXIT_CODE>
     */
    quit
};

union Argument {
    int num;
    char *str;
};

struct Instruction {
    /* type of command determines dispatch to eval_ function
     * which in turn determines which Argument member to use
     */
    enum Command command;
    union Argument argument;
    /* next Instruction in linked list */
    struct Instruction *next;
};

struct Program {
    /* linked list of Instruction(s) */
    struct Instruction *start;
    /* file program is operating on */
    FILE *file;
    /* program source read into a buffer */
    char *source;
    /* shared buffer (and length) used for reading into */
    char *buf;
    size_t buf_len;
};

struct Instruction *new_instruction(enum Command command){
    struct Instruction *i;

    i = calloc(1, sizeof(struct Instruction));
    if( ! i ){
        puts("new_instruction: call to calloc failed");
        return 0;
    }

    i->command = command;

    return i;
}

/***** internal helpers ******/
/* return a buffer of at least size required_len
 * returns 0 on error
 */
char *get_buffer(struct Program *p, size_t required_len){
    if( !p )
        return 0;

    if( p->buf_len <= required_len )
        return p->buf;

    p->buf_len = required_len;
    p->buf = realloc(p->buf, required_len);

    if( ! p->buf_len ){
        puts("get_buffer: failed to allocate buffer");
        return 0;
    }

    return p->buf;
}

#define BUF_INCR 1024

/* return a char* containing data from provided FILE*
 * returns 0 on error
 */
char * slurp(FILE *file){
    size_t size = BUF_INCR;
    size_t offset = 0;
    size_t nr = 0;
    char *buf;

    if( ! file ){
        return 0;
    }

    buf = malloc(size);
    if( ! buf ){
        return 0;
    }

    while( BUF_INCR == (nr = fread(&(buf[offset]), 1, BUF_INCR, file)) ){
        offset = size;
        size += BUF_INCR;

        buf = realloc(buf, size);

        if( ! buf ){
            return 0;
        }
    }

    /* check for fread errors */
    if( ferror(file) ){
        puts("slurp: file read failed");
        return 0;
    }

    return buf;
}


/***** parsing functions *****/

struct Instruction * parse_print(char *source, int *index){
    struct Instruction *i;

    i = new_instruction(print);
    if( ! i ){
        puts("Parse_print: call to new_instruction failed");
        return 0;
    }

    puts("parse_print unimplemented");
    return 0; /* FIXME unimplemented */
}

struct Instruction * parse_byte(char *source, int *index){
    struct Instruction *i;

    i = new_instruction(byte);
    if( ! i ){
        puts("Parse_byte: call to new_instruction failed");
        return 0;
    }
{'fraction_non_alphanumeric': 0.11547379811408255, 'fraction_numerical': 0.005565002318750966, 'mean_word_length': 2.3768267223382047, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 29, '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': '6040114', 'n_tokens_mistral': 2047, 'n_tokens_neox': 1940, 'n_words': 665}