<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <math.h>

#include "debug.h"

static const char* getfield(char* line, int num)
{
    const char* tok;
    for (tok = strtok(line, ",");
            tok && *tok;
            tok = strtok(NULL, ",\n"))
    {
        if (!--num)
            return tok;
    }
    return NULL;
}

#define BUF_SIZE 10000

#define NCHANNELS 32
#define NSESSIONS 8
#define EVLEN 150

typedef sax_word sax_signal[NCHANNELS];

struct sax_signal_set {
    sax_signal *series;
    size_t n_series;
};

struct session {
    double **series;
    size_t n_series;
};

void *safe_realloc(void *mem, size_t size) {
    void *new_mem = realloc(mem, size);
    if (!new_mem) {
        printf("Unable to allocate more mem, exiting\n");
        exit(-1);
    }
    return new_mem;
}

void *safe_malloc(size_t size) {
    void *new_mem = malloc(size);
    if (!new_mem) {
        printf("Unable to allocate more mem, exiting\n");
        exit(-1);
    }
    return new_mem;
}

void push_back(double* *series, size_t* size, double value) {
    *series = safe_realloc(*series, (++(*size)) * sizeof(double)); \
    (*series)[(*size) - 1] = value;
}

void push_back_pointer(double* **series, size_t* size, double* value) {
    *series = safe_realloc(*series, (++(*size)) * sizeof(double*)); \
    (*series)[(*size) - 1] = value;
}

void push_back_buffer(double* *val_buffer, size_t* n_values, double value, 
        double* **series, size_t* n_trials) {
    push_back(val_buffer, n_values, value);
    if (*n_values >= EVLEN) {
        double *new_subseq = safe_malloc(EVLEN * sizeof(double));
        memcpy(new_subseq, *val_buffer + (*n_values - EVLEN), EVLEN);
        push_back_pointer(series, n_trials, new_subseq);
    }
}

static double signal_dist(sax_signal signal1, sax_signal signal2, 
        size_t n, size_t w, unsigned int c) {
    double dist = 0, idist;
    for (size_t i = 0; i < NCHANNELS; ++i) {
        idist = sts_mindist(signal1[i], signal2[i], n, w, c);
        dist += idist * idist;
    }
    return sqrt(dist);
}

/*
 * Parses subject-specific files in train and 
 * returns the subrange corresponding to specified activity
 * @param evid: 1-based id of the event. 
 * If evid is negative than each subrange not corresponding to event #evid 
 * of length EVLEN will be returned
 * If evid is zero, than all session subsequences of length EVLEN will be returned
 */
struct session fetch_session_data(int pid, int chid, int sid, int evid) {
    char buf[BUF_SIZE];
    snprintf(buf, BUF_SIZE, 
            "data/train/subj%d_series%d_data.csv", pid + 1, sid + 1);
    FILE *dataf = fopen(buf, "r");
    snprintf(buf, BUF_SIZE, 
            "data/train/subj%d_series%d_events.csv", pid + 1, sid + 1);
    FILE *eventsf = fopen(buf, "r");
    // Eat-up both csv headers
    if (fgets(buf, BUF_SIZE, dataf) == NULL) return (struct session) {NULL, 0};
    if (fgets(buf, BUF_SIZE, eventsf) == NULL) return (struct session) {NULL, 0};

    size_t n_values = 0, n_trials = 0;
    int new = 1;
    double *val_buffer = NULL;
    double **series = NULL;<commit_msg>Added more I/O safechecks<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <math.h>

#include "debug.h"

static const char* getfield(char* line, int num)
{
    const char* tok;
    for (tok = strtok(line, ",");
            tok && *tok;
            tok = strtok(NULL, ",\n"))
    {
        if (!--num)
            return tok;
    }
    return NULL;
}

#define BUF_SIZE 10000

#define NCHANNELS 32
#define NSESSIONS 8
#define EVLEN 150

typedef sax_word sax_signal[NCHANNELS];

struct sax_signal_set {
    sax_signal *series;
    size_t n_series;
};

struct session {
    double **series;
    size_t n_series;
};

void *safe_realloc(void *mem, size_t size) {
    void *new_mem = realloc(mem, size);
    if (!new_mem) {
        printf("Unable to allocate more mem, exiting\n");
        exit(-1);
    }
    return new_mem;
}

void *safe_malloc(size_t size) {
    void *new_mem = malloc(size);
    if (!new_mem) {
        printf("Unable to allocate more mem, exiting\n");
        exit(-1);
    }
    return new_mem;
}

void push_back(double* *series, size_t* size, double value) {
    *series = safe_realloc(*series, (++(*size)) * sizeof(double)); \
    (*series)[(*size) - 1] = value;
}

void push_back_pointer(double* **series, size_t* size, double* value) {
    *series = safe_realloc(*series, (++(*size)) * sizeof(double*)); \
    (*series)[(*size) - 1] = value;
}

void push_back_buffer(double* *val_buffer, size_t* n_values, double value, 
        double* **series, size_t* n_trials) {
    push_back(val_buffer, n_values, value);
    if (*n_values >= EVLEN) {
        double *new_subseq = safe_malloc(EVLEN * sizeof(double));
        memcpy(new_subseq, *val_buffer + (*n_values - EVLEN), EVLEN);
        push_back_pointer(series, n_trials, new_subseq);
    }
}

static double signal_dist(sax_signal signal1, sax_signal signal2, 
        size_t n, size_t w, unsigned int c) {
    double dist = 0, idist;
    for (size_t i = 0; i < NCHANNELS; ++i) {
        idist = sts_mindist(signal1[i], signal2[i], n, w, c);
        dist += idist * idist;
    }
    return sqrt(dist);
}

/*
 * Parses subject-specific files in train and 
 * returns the subrange corresponding to specified activity
 * @param evid: 1-based id of the event. 
 * If evid is negative than each subrange not corresponding to event #evid 
 * of length EVLEN will be returned
 * If evid is zero, than all session subsequences of length EVLEN will be returned
 */
struct session fetch_session_data(int pid, int chid, int sid, int evid) {
    char buf[BUF_SIZE];
    snprintf(buf, BUF_SIZE, 
            "data/train/subj%d_series%d_data.csv", pid + 1, sid + 1);
    FILE *dataf = fopen(buf, "r");
    snprintf(buf, BUF_SIZE, 
            "data/train/subj%d_series%d_events.csv", pid + 1, sid + 1);
    FILE *eventsf = fopen(buf, "r");
    if (!dataf || !eventsf) return (struct session) {NULL, 0};
    // Eat-up both csv headers
    if (fgets(buf, BUF_SIZE, dataf) == NULL) return (struct session) {NULL, 0};
    if (fgets(buf, BUF_SIZE, eventsf) == NULL) return (struct session) {NULL, 0};

    size_t n_values = 0, n_trials = 0;
    int new = 1;
    double *val_buffer = NULL;
    double **series = NULL;
{'fraction_non_alphanumeric': 0.1353905211870663, 'fraction_numerical': 0.01048279935036173, 'mean_word_length': 3.0660264105642256, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, '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': '7176120', 'n_tokens_mistral': 2462, 'n_tokens_neox': 2348, 'n_words': 712}