<commit_before>#include <stdio.h>

#include "sdc.hpp"
#include "sdc_common.hpp"

#include "sdc_lexer.hpp"
#include "sdc_error.hpp"

namespace sdcparse {

/*
 * Given a filename parses the file as an SDC file
 * and returns a pointer to a struct containing all
 * the sdc commands.  See sdc.h for data structure
 * detials.
 */
std::shared_ptr<SdcCommands> sdc_parse_filename(std::string filename) {
    return sdc_parse_filename(filename.c_str());
}

std::shared_ptr<SdcCommands> sdc_parse_filename(const char* filename) {
    std::shared_ptr<SdcCommands> sdc_commands;

    FILE* infile = fopen(filename, "r");
    if(infile != NULL) {
        sdc_commands = sdc_parse_file(infile);
        fclose(infile);
    } else {
        fclose(infile);
        sdc_error_wrap(0, "", "Could not open file %s.\n", filename);
    }

    return sdc_commands;
}

std::shared_ptr<SdcCommands> sdc_parse_file(FILE* sdc_file) {

    //Initialize the lexer
    Lexer lexer(sdc_file);

    auto sdc_commands = std::make_shared<SdcCommands>();

    //Setup the pares + lexer
    Parser parser(lexer, sdc_commands);

    //Do the parse
    int error = parser.parse();
    if(error) {
        sdc_error_wrap(0, "", "SDC Error: file failed to parse!\n");
    }

    return sdc_commands;
}

/*
 * Error handling
 */
void default_sdc_error(const int line_no, const std::string& near_text, const std::string& msg) {
    fprintf(stderr, "SDC Error line %d near '%s': %s\n", line_no, near_text.c_str(), msg.c_str());
    exit(1);
}

void set_sdc_error_handler(std::function<void(const int, const std::string&, const std::string&)> new_sdc_error_handler) {
    sdc_error = new_sdc_error_handler;
}

/*
 * Class member functions
 */

bool SdcCommands::has_commands() {
    if(!create_clock_cmds.empty()) return true;
    if(!set_input_delay_cmds.empty()) return true;
    if(!set_output_delay_cmds.empty()) return true;
    if(!set_clock_groups_cmds.empty()) return true;
    if(!set_false_path_cmds.empty()) return true;
    if(!set_max_delay_cmds.empty()) return true;
    if(!set_multicycle_path_cmds.empty()) return true;
    return false; 
}

}
<commit_msg>Fix invalid call to fclose()<commit_after>#include <stdio.h>

#include "sdc.hpp"
#include "sdc_common.hpp"

#include "sdc_lexer.hpp"
#include "sdc_error.hpp"

namespace sdcparse {

/*
 * Given a filename parses the file as an SDC file
 * and returns a pointer to a struct containing all
 * the sdc commands.  See sdc.h for data structure
 * detials.
 */
std::shared_ptr<SdcCommands> sdc_parse_filename(std::string filename) {
    return sdc_parse_filename(filename.c_str());
}

std::shared_ptr<SdcCommands> sdc_parse_filename(const char* filename) {
    std::shared_ptr<SdcCommands> sdc_commands;

    FILE* infile = fopen(filename, "r");
    if(infile != NULL) {
        sdc_commands = sdc_parse_file(infile);
        fclose(infile);
    } else {
        sdc_error_wrap(0, "", "Could not open file %s.\n", filename);
    }

    return sdc_commands;
}

std::shared_ptr<SdcCommands> sdc_parse_file(FILE* sdc_file) {

    //Initialize the lexer
    Lexer lexer(sdc_file);

    auto sdc_commands = std::make_shared<SdcCommands>();

    //Setup the pares + lexer
    Parser parser(lexer, sdc_commands);

    //Do the parse
    int error = parser.parse();
    if(error) {
        sdc_error_wrap(0, "", "SDC Error: file failed to parse!\n");
    }

    return sdc_commands;
}

/*
 * Error handling
 */
void default_sdc_error(const int line_no, const std::string& near_text, const std::string& msg) {
    fprintf(stderr, "SDC Error line %d near '%s': %s\n", line_no, near_text.c_str(), msg.c_str());
    exit(1);
}

void set_sdc_error_handler(std::function<void(const int, const std::string&, const std::string&)> new_sdc_error_handler) {
    sdc_error = new_sdc_error_handler;
}

/*
 * Class member functions
 */

bool SdcCommands::has_commands() {
    if(!create_clock_cmds.empty()) return true;
    if(!set_input_delay_cmds.empty()) return true;
    if(!set_output_delay_cmds.empty()) return true;
    if(!set_clock_groups_cmds.empty()) return true;
    if(!set_false_path_cmds.empty()) return true;
    if(!set_max_delay_cmds.empty()) return true;
    if(!set_multicycle_path_cmds.empty()) return true;
    return false; 
}

}

{'fraction_non_alphanumeric': 0.13225276015973692, 'fraction_numerical': 0.0014094432699083862, 'mean_word_length': 4.045023696682464, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, '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': '5468307', 'n_tokens_mistral': 1539, 'n_tokens_neox': 1530, 'n_words': 337}