ImplementFunctionPointers.refscript

This page describes the ImplementFunctionPointers RefactorScript shipped with VisualGDB.

Overview

This script generates C functions based on the function pointer fields.
In order to run this script, first select one or more function pointer fields (or structs containing them)
in the Code Explorer -> Outline view.

Script


[Main, Description("Implement function pointers")]
generator GenerateMockClass(Array structOrFields,
                            string namePrefix = "my_",
                            bool static = true)
{
    if ((structOrFields.Length == 1) && (structOrFields.First is Record))
        DoImplementFunctionPointers(structOrFields.First,
                                    structOrFields.First.NonStaticFields,
                                    namePrefix,
                                    static);
    else
        DoImplementFunctionPointers(structOrFields.First.ContainingType,
                                    structOrFields,
                                    namePrefix,
                                    static);
}

generator GenerateFunctionDeclaration(Field field,
                                      string prefix,
                                      string namePrefix,
                                      bool semicolon)
{
>>$modifier$field.Type.ReturnType.Literal $prefix$field.ShortName(
    foreach(arg in field.Type.Arguments)
    {
>>$arg.Type.Literal $arg.ShortName$arg.Type.LiteralSuffix
        if (!arg.IsLast)
>>, 
    }
>>)
    if (semicolon)
>>;
>
}

generator GenerateDefaultBody(TypeRef returnType, Array args)
{
    //This generator can be used to produce the default return statement/NULL checks.
}

generator DoImplementFunctionPointers(Record struct,
                                      Array fields,
                                      string namePrefix,
                                      bool static)
{
>//Forward declarations
    set modifier = "";
    if (static)
        set modifier = "static ";

    foreach(field in fields)
        if (field.Type is FunctionPrototype)
            GenerateFunctionDeclaration(field, namePrefix, modifier, true);
>
>//Definitions

    foreach(field in fields)
        if (field.Type is FunctionPrototype)
        {
            GenerateFunctionDeclaration(field, namePrefix, modifier, false);
>{
            GenerateDefaultBody(field.Type.ReturnType, field.Type.Arguments);
>}
>
        }

>//Instance
>
>struct $struct.ShortName $namePrefix$struct.ShortName =
>{
    foreach(field in fields)
        if (field.Type is FunctionPrototype)
            >    .$field.ShortName = $namePrefix$field.ShortName,
>};


}

Sample Input

typedef int (*PINTADDER)(int x, int y);

struct StructWithFunctionPointers
{
    double (*AddDoubles)(double x, double y);
    PINTADDER AddInts;
};

Sample Output

//Forward declarations
static double my_AddDoubles(double x, double y);
static int my_AddInts(int x, int y);

//Definitions
static double my_AddDoubles(double x, double y)
{
}

static int my_AddInts(int x, int y)
{
}

//Instance

struct StructWithFunctionPointers my_StructWithFunctionPointers =
{
    .AddDoubles = my_AddDoubles,
    .AddInts = my_AddInts,
};
A detailed reference on RefactorScript syntax and data model is available here.
See this page for a full list of RefactorScripts shipped with VisualGDB.