Comment out a line using text based design modification and parsetree modification

From Verific Design Automation FAQ
Jump to: navigation, search

C++:

#include <iostream>

#include "veri_file.h"

#include "VeriModule.h"
#include "VeriStatement.h"

#include "Array.h"

#include "Strings.h"
#include "TextBasedDesignMod.h"

#ifdef VERIFIC_NAMESPACE
using namespace Verific ;
#endif

void CommentStmtInParseTree(VeriModule *mod)
{
    if (!mod) return ;

    Array *mod_items = mod->GetModuleItems() ;
    unsigned i ;
    VeriModuleItem *item ;
    FOREACH_ARRAY_ITEM(mod_items, i, item) {
        if (!item) continue ;
        // Get statement from the module item (initial block)
        VeriStatement *stmt = item->GetStmt() ;
        if (!stmt) continue ;
        // Get all statements from the statement (squential block in initial block)
        Array *stmts = stmt->GetStatements() ;
        if (stmts) {
            unsigned j ;
            VeriStatement *child ;
            // Iterate over the child statement:
            FOREACH_ARRAY_ITEM(stmts, j, child) {
                if (!child) continue ;
                // Get the string of the statement:
                char *tmp = child->GetPrettyPrintedString() ;
                // Remove the last new-line:
                unsigned len = Strings::len(tmp) ;
                if (!tmp || !len) continue ;
                if (tmp[len-1] == '\n') tmp[len-1] = '\0' ;
                // Comment out the string:
                char *str = Strings::save("/* ", tmp, " */") ;
                Strings::free(tmp) ;
                // Create a null statement:
                VeriStatement *new_stmt = new VeriNullStatement() ;
                new_stmt->SetLinefile(child->Linefile()) ;
                // Create a comment node with the comment string:
                VeriCommentNode *comment = new VeriCommentNode(child->Linefile()) ;
                comment->AppendComment(str) ;
                Strings::free(str) ;
                // Add the comment on the null-statement:
                Array *comments = new Array(1) ;
                comments->InsertLast(comment) ;
                new_stmt->AddComments(comments) ;
                // Finally replace the original statement with the created null-statement:
                if (!stmt->ReplaceChildStmt(child, new_stmt, 1 /* delete old stmt */)) delete new_stmt ;
            }
        } else {
                // Get the string of the statement:
            char *tmp = stmt->GetPrettyPrintedString() ;
                // Remove the last new-line:
            unsigned len = Strings::len(tmp) ;
            if (!tmp || !len) continue ;
            if (tmp[len-1] == '\n') tmp[len-1] = '\0' ;
                // Comment out the string:
            char *str = Strings::save("/* ", tmp, " */") ;
            Strings::free(tmp) ;
                // Create a null statement:
            VeriStatement *new_stmt = new VeriNullStatement() ;
            new_stmt->SetLinefile(stmt->Linefile()) ;
            // Create a comment node with the comment string:
            VeriCommentNode *comment = new VeriCommentNode(stmt->Linefile()) ;
            comment->AppendComment(str) ;
            Strings::free(str) ;
            // Add the comment on the null-statement:
            Array *comments = new Array(1) ;
            comments->InsertLast(comment) ;
            new_stmt->AddComments(comments) ;
            // Finally replace the original statement with the created null-statement:
            if (!item->ReplaceChildStmt(stmt, new_stmt, 1 /* delete old stmt */)) delete new_stmt ;
        }
    }

    veri_file::PrettyPrint("test_pp.v.golden.new", 0) ;
}

void CommentStmtViaTBDM(VeriModule *mod, TextBasedDesignMod &tbdm)
{
    if (!mod) return ;

    Array *mod_items = mod->GetModuleItems() ;
    unsigned i ;
    VeriModuleItem *item ;
    FOREACH_ARRAY_ITEM(mod_items, i, item) {
        if (!item) continue ;
        // Get statement from the module item (initial block)
        VeriStatement *stmt = item->GetStmt() ;
        if (!stmt) continue ;
        // Get all statements from the statement (squential block in initial block)
        Array *stmts = stmt->GetStatements() ;
        if (stmts) {
            unsigned j ;
            VeriStatement *child ;
            // Iterate over the child statement:
            FOREACH_ARRAY_ITEM(stmts, j, child) {
                if (!child) continue ;
                // Comment the whole statement:
                tbdm.InsertBefore(child->Linefile(), "; /* ") ;
                tbdm.InsertAfter(child->Linefile(), " */") ;
            }
        } else {
            // Comment the whole statement:
            tbdm.InsertBefore(stmt->Linefile(), "; /* ") ;
            tbdm.InsertAfter(stmt->Linefile(), " */") ;
        }
    }
}

int main()
{
    if (!veri_file::Analyze("test.v")) return 1 ;

    VeriModule *mod = veri_file::GetModule("test") ;
    if (!mod) return 2 ;

    CommentStmtInParseTree(mod) ;

    TextBasedDesignMod tbdm(0) ;
    CommentStmtViaTBDM(mod, tbdm) ;
    tbdm.WriteFile("test.v", "test_out.v.golden.new") ;

    return 0 ;
}
 

Input Verilog:

module test ;
    reg A, b ;
    initial
        A = b ;
    initial
    begin
        A = b ;
    end
endmodule

Output Verilog:

module test ;
    reg A, b ;
    initial
        ; /* A = b ; */
    initial
    begin
        ; /* A = b ; */
    end
endmodule