<commit_before>/*!
@file verilog_preprocessor.c
@brief Contains function implementations to support source code preprocessing.
*/

#include "verilog_preprocessor.h"

verilog_preprocessor_context * verilog_new_preprocessor_context()
{
    verilog_preprocessor_context * tr = 
        ast_calloc(1,sizeof(verilog_preprocessor_context));

    tr -> token_count    = 0;
    tr -> in_cell_define = AST_FALSE;
    tr -> emit           = AST_TRUE;

    tr -> includes       = ast_list_new();
    tr -> net_types      = ast_list_new();
    tr -> unconnected_drive_pull = STRENGTH_NONE;
    tr -> macrodefines   = ast_hashtable_new();
    tr -> ifdefs         = ast_stack_new();

    return tr;
}


void verilog_free_preprocessor_context(verilog_preprocessor_context * tofree)
{
    ast_list_free(tofree -> includes);
    ast_list_free(tofree -> net_types);
    ast_hashtable_free(tofree -> macrodefines);
    ast_stack_free(tofree -> ifdefs);
    free(tofree);
}

void verilog_preproc_enter_cell_define()
{
    yy_preproc -> in_cell_define = AST_FALSE;
}

void verilog_preproc_exit_cell_define()
{
    yy_preproc -> in_cell_define = AST_FALSE;
}

//! Creates and returns a new default net type directive.
verilog_default_net_type * verilog_new_default_net_type(
    unsigned int token_number,  //!< Token number of the directive.
    unsigned int line_number,   //!< Line number of the directive.
    ast_net_type type           //!< The net type.
){
    verilog_default_net_type * tr = 
        ast_calloc(1,sizeof(verilog_default_net_type));

    tr -> token_number = token_number;
    tr -> line_number  = line_number;
    tr -> type         = type;

    return tr;
}

/*!
@brief Registers a new default net type directive.
@details Adds a record of the directive to the end of the linked list
"net_types" in the global yy_preproc.
*/
void verilog_preproc_default_net(
    unsigned int token_number,  //!< Token number of the directive.
    unsigned int line_number,   //!< Line number of the directive.
    ast_net_type type           //!< The net type.
){
    verilog_default_net_type * directive = verilog_new_default_net_type(
        token_number,
        line_number,
        type
    );

    ast_list_append(yy_preproc -> net_types, directive);
}


/*!
@brief Handles the encounter of a `resetall directive as described in annex
19.6 of the spec.
*/
void verilog_preprocessor_resetall()
{
    return;
}


/*!
@brief Handles the entering of a no-unconnected drive directive.
*/
void verilog_preprocessor_nounconnected_drive(
    ast_primitive_strength direction
){
    assert(direction == STRENGTH_PULL1 ||
           direction == STRENGTH_PULL0 ||
           direction == STRENGTH_NONE);

    yy_preproc -> unconnected_drive_pull = direction;
}


/*! 
@brief Handles the encounter of an include directive.
@returns A pointer to the newly created directive reference.
*/
verilog_include_directive * verilog_preprocessor_include(
    char * filename,
    unsigned int lineNumber
){
    verilog_include_directive * toadd = 
        ast_calloc(1,sizeof(verilog_include_directive));

    filename = filename + 1; // Remove leading quote mark.
    size_t length = strlen(filename);
    
    toadd -> filename = calloc(length,sizeof(char));
    memcpy(toadd -> filename, filename, length-1); // Remove trailing quote.
    toadd -> lineNumber = lineNumber;

    ast_list_append(yy_preproc -> includes, toadd);

    FILE * handle = fopen(toadd -> filename,"r");
    if(handle)
    {
        fclose(handle);
        toadd -> file_found = AST_TRUE;
    }
    else
    {   
        toadd -> file_found = AST_FALSE;
    }

    return toadd;
}

/*
@brief Instructs the preprocessor to register a new macro definition.
*/
void verilog_preprocessor_macro_define(
    unsigned int line,  //!< The line the defininition comes from.
    char * macro_name,  //!< The macro identifier.
    size_t name_len  ,  //!< Length in bytes of macro_name.
    char * macro_text,  //!< The value the macro expands to.
    size_t text_len     //!< Length in bytes of macro_text.
){
    verilog_macro_directive * toadd = 
        ast_calloc(1, sizeof(verilog_macro_directive));
    
    toadd -> line = line;

    //printf("\nEncountered macro '%s' on line %d ", toadd -> macro_id, line);
    //printf("with value '%s'\n", toadd -> macro_value);
    //fflush(stdout);

    // Make space for, and duplicate, the macro text, into the thing
    // we will put into the hashtable.
    toadd -> macro_id    = calloc(name_len,sizeof(char));
    memcpy(toadd -> macro_id,macro_name, name_len);

    if(text_len > 0){
        toadd -> macro_value = calloc(text_len,sizeof(char));
        memcpy(toadd -> macro_value,macro_text,text_len);
    } else {
        toadd -> macro_value = NULL;
    }

    ast_hashtable_insert(
        yy_preproc -> macrodefines,
        toadd -> macro_id,
        toadd
    );<commit_msg>Strip macro_text values of single line comment endings.  On branch master  Your branch is ahead of 'origin/master' by 6 commits.    (use "git push" to publish your local commits)<commit_after>/*!
@file verilog_preprocessor.c
@brief Contains function implementations to support source code preprocessing.
*/

#include "verilog_preprocessor.h"

verilog_preprocessor_context * verilog_new_preprocessor_context()
{
    verilog_preprocessor_context * tr = 
        ast_calloc(1,sizeof(verilog_preprocessor_context));

    tr -> token_count    = 0;
    tr -> in_cell_define = AST_FALSE;
    tr -> emit           = AST_TRUE;

    tr -> includes       = ast_list_new();
    tr -> net_types      = ast_list_new();
    tr -> unconnected_drive_pull = STRENGTH_NONE;
    tr -> macrodefines   = ast_hashtable_new();
    tr -> ifdefs         = ast_stack_new();

    return tr;
}


void verilog_free_preprocessor_context(verilog_preprocessor_context * tofree)
{
    ast_list_free(tofree -> includes);
    ast_list_free(tofree -> net_types);
    ast_hashtable_free(tofree -> macrodefines);
    ast_stack_free(tofree -> ifdefs);
    free(tofree);
}

void verilog_preproc_enter_cell_define()
{
    yy_preproc -> in_cell_define = AST_FALSE;
}

void verilog_preproc_exit_cell_define()
{
    yy_preproc -> in_cell_define = AST_FALSE;
}

//! Creates and returns a new default net type directive.
verilog_default_net_type * verilog_new_default_net_type(
    unsigned int token_number,  //!< Token number of the directive.
    unsigned int line_number,   //!< Line number of the directive.
    ast_net_type type           //!< The net type.
){
    verilog_default_net_type * tr = 
        ast_calloc(1,sizeof(verilog_default_net_type));

    tr -> token_number = token_number;
    tr -> line_number  = line_number;
    tr -> type         = type;

    return tr;
}

/*!
@brief Registers a new default net type directive.
@details Adds a record of the directive to the end of the linked list
"net_types" in the global yy_preproc.
*/
void verilog_preproc_default_net(
    unsigned int token_number,  //!< Token number of the directive.
    unsigned int line_number,   //!< Line number of the directive.
    ast_net_type type           //!< The net type.
){
    verilog_default_net_type * directive = verilog_new_default_net_type(
        token_number,
        line_number,
        type
    );

    ast_list_append(yy_preproc -> net_types, directive);
}


/*!
@brief Handles the encounter of a `resetall directive as described in annex
19.6 of the spec.
*/
void verilog_preprocessor_resetall()
{
    return;
}


/*!
@brief Handles the entering of a no-unconnected drive directive.
*/
void verilog_preprocessor_nounconnected_drive(
    ast_primitive_strength direction
){
    assert(direction == STRENGTH_PULL1 ||
           direction == STRENGTH_PULL0 ||
           direction == STRENGTH_NONE);

    yy_preproc -> unconnected_drive_pull = direction;
}


/*! 
@brief Handles the encounter of an include directive.
@returns A pointer to the newly created directive reference.
*/
verilog_include_directive * verilog_preprocessor_include(
    char * filename,
    unsigned int lineNumber
){
    verilog_include_directive * toadd = 
        ast_calloc(1,sizeof(verilog_include_directive));

    filename = filename + 1; // Remove leading quote mark.
    size_t length = strlen(filename);
    
    toadd -> filename = calloc(length,sizeof(char));
    memcpy(toadd -> filename, filename, length-1); // Remove trailing quote.
    toadd -> lineNumber = lineNumber;

    ast_list_append(yy_preproc -> includes, toadd);

    FILE * handle = fopen(toadd -> filename,"r");
    if(handle)
    {
        fclose(handle);
        toadd -> file_found = AST_TRUE;
    }
    else
    {   
        toadd -> file_found = AST_FALSE;
    }

    return toadd;
}

/*
@brief Instructs the preprocessor to register a new macro definition.
*/
void verilog_preprocessor_macro_define(
    unsigned int line,  //!< The line the defininition comes from.
    char * macro_name,  //!< The macro identifier.
    size_t name_len  ,  //!< Length in bytes of macro_name.
    char * macro_text,  //!< The value the macro expands to.
    size_t text_len     //!< Length in bytes of macro_text.
){
    verilog_macro_directive * toadd = 
        ast_calloc(1, sizeof(verilog_macro_directive));
    
    toadd -> line = line;

    //printf("\nEncountered macro '%s' on line %d ", toadd -> macro_id, line);
    //printf("with value '%s'\n", toadd -> macro_value);
    //fflush(stdout);

    // Make space for, and duplicate, the macro text, into the thing
    // we will put into the hashtable.
    toadd -> macro_id    = calloc(name_len,sizeof(char));
    memcpy(toadd -> macro_id,macro_name, name_len);

    if(text_len > 0){
        // Make sure we exclude all comments from the macro text.
        int i = 0;
        for(i = 0; i < text_len-1; i++)
        {
            if(macro_text[i]   == '/' &&
               macro_text[i+1] == '/')
            {
                text_len = (size_t)i;
                break;
            }
        }

        toadd -> macro_value = calloc(text_len,sizeof(char));
        memcpy(toadd -> macro_value,macro_text,text_len);
    } else {
        toadd -> macro_value = NULL;
    }

    //printf("MACRO: '%s' - '%s'\n", toadd -> macro_id, toadd -> macro_value);

    ast_hashtable_insert(
        yy_preproc -> macrodefines,
        toadd -> macro_id,
        toadd
    );
{'fraction_non_alphanumeric': 0.10172614429790536, 'fraction_numerical': 0.0030062063615205587, 'mean_word_length': 2.891698113207547, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 79, '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': '7527639', 'n_tokens_mistral': 3415, 'n_tokens_neox': 3283, 'n_words': 839}