Question

I'm trying to modify/refactor input C source code. I'm trying to add a printf statement after every line of my input code.

For e.g. if my input is -

void foo(){
    // Sample input code
    int a = 0, b = 0;
    a++;
    if(a<5)
         b++;
    b--;
}

I would want to add the statement printf('Hi');, leading to -

void foo(){
    int a = 0, b = 0;
    printf('Hi');
    a++;
    printf('Hi');
    if(a<5){
         b++;
         printf('Hi');
    }
    printf('Hi');
    b--;
    printf('Hi');
}

As an initial step, I simply tried declaring a variable test and tried inserting it to the beginning of the AST generated by a random source code. Here's the python code that I was involved with, after having extracted the AST to the object ast -

for i in range(0,len(ast.ext)):
    ## Look for a function named 'foo'
    if(type(ast.ext[i]) == c_ast.FuncDef and ast.ext[i].decl.name == 'foo'):
        ## Store the list of AST node objects in functionBody
        functionBody    = ast.ext[i].body

        ## Create a Decl object for the variable test
        id_obj          = c_ast.ID('test')
        identifier_obj  = c_ast.IdentifierType(['int'])
        typedecl_obj    = c_ast.TypeDecl(id_obj.name,[],identifier_obj)
        decl_obj        = c_ast.Decl(id_obj.name,[],[],[],typedecl_obj,[],[])

        ## Append the object to a list.
        ## Concatenate to a copy of existing list of AST objects     
        lst1 = []
        lst1.append(decl_obj)
        lst2 = []
        lst2 = copy.deepcopy(functionBody.block_items)
        lst3 = []
        lst3 = lst1+lst2

        ## Create a modified AST and print content
        functionBody1 = c_ast.Compound(lst3)
        functionBody1.show()

I find no change in the resulting structure functionBody1 and also get the following error whenever I try to use its show( ) method.

'list' object has no attribute 'show'

Any idea as to where I'm going off track?

Thanks

Was it helpful?

Solution

I found three places where you were passing a list where you should have been passing None.

## Create a Decl object for the variable test
id_obj          = c_ast.ID('test')
identifier_obj  = c_ast.IdentifierType(['int'])
typedecl_obj    = c_ast.TypeDecl(id_obj.name,None,identifier_obj)
decl_obj        = c_ast.Decl(id_obj.name,[],[],[],typedecl_obj,None,None)

I am not really that familiar with this, as I am still learning pycparser too, but this change fixes your traceback for me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top