10

I want to generate empty implementations of procedures defined in a header file. Ideally they should return NULL for pointers, 0 for integers, etc, and, in an ideal world, also print to stderr which function was called.

The motivation for this is the need to implement a wrapper that adapts a subset of a complex, existing API (the header file) to another library. Only a small number of the procedures in the API need to be delegated, but it's not clear which ones. So I hope to use an iterative approach, where I run against this auto-generated wrapper, see what is called, implement that with delegation, and repeat.

I've see Automatically generate C++ file from header? but the answers appear to be C++ specific.

So, for people that need the question spelled out in simple terms, how can I automate the generation of such an implementation given the header file? I would prefer an existing tool - my current best guess at a simple solution is using pycparser.

update Thanks guys. Both good answers. Also posted my current hack.

6
  • Now you haven't really asked a question as far as I see, but I'm guessing your asking for an existing tool that can do this? Unfortunately I don't know any tool, but it sounds basic enough to do a quick python(or any other high level language) implementation to solve it? Commented Dec 10, 2012 at 13:52
  • i've clarified the question. yes, i can write a program to do this. but it's not trivial - it requires a decent parser, for example. the header is large enough, and complex enough, that an ad-hoc regexp based kludge is going to be a time consuming mess. Commented Dec 10, 2012 at 14:00
  • Hi, does the process need to be easily repeatable? For instance, would you want to be able to update the stub implementation when new versions of the API are released? Commented Dec 10, 2012 at 14:02
  • oh good question. no, that's not necessary (it would be better if so, but i can see it making things hugely more complicated, and it's a standard API that is unlikely to change significantly). Commented Dec 10, 2012 at 14:04
  • If you're comfortable with scripting, perhaps you can write your own tool? This looks like a relatively straight-forward task that regular expressions can handle... Commented Dec 10, 2012 at 14:04

3 Answers 3

2

so, i'm going to mark the ea suggestion as the "answer" because i think it's probably the best idea in general. although i think that the cmock suggestion would work very well in tdd approach where the library development was driven by test failures, and i may end up trying that. but for now, i need a quicker + dirtier approach that works in an interactive way (the library in question is a dynamically loaded plugin for another, interactive, program, and i am trying to reverse engineer the sequence of api calls...)

so what i ended up doing was writing a python script that calls pycparse. i'll include it here in case it helps others, but it is not at all general (assumes all functions return int, for example, and has a hack to avoid func defs inside typedefs).

from pycparser import parse_file
from pycparser.c_ast import NodeVisitor


class AncestorVisitor(NodeVisitor):

    def __init__(self):
        self.current = None
        self.ancestors = []

    def visit(self, node):
        if self.current:
            self.ancestors.append(self.current)
        self.current = node
        try:
            return super(AncestorVisitor, self).visit(node)
        finally:
            if self.ancestors:
                self.ancestors.pop(-1)


class FunctionVisitor(AncestorVisitor):

    def visit_FuncDecl(self, node):
        if len(self.ancestors) < 3: # avoid typedefs
            print node.type.type.names[0], node.type.declname, '(',
            first = True
            for param in node.args.params:
                if first: first = False
                else: print ',',
                print param.type.type.names[0], param.type.declname,
            print ')'
            print '{fprintf(stderr, "%s\\n"); return 0;}' % node.type.declname


print '#include "myheader.h"'
print '#include <stdio.h>'
ast = parse_file('myheader.h', use_cpp=True)
FunctionVisitor().visit(ast)
Sign up to request clarification or add additional context in comments.

Comments

1

UML modeling tools are capable of generating default implementation in the language of choice. Generally there is also a support for importing source code (including C headers). You can try to import your headers and generate source code from them. I personally have experience with Enterprise Architect and it supports both of these operations.

3 Comments

ah yes, ea would probably do this (though not the print statements). although maybe only in the paid version, and i haven't had a licence for years. will check it out. thanks.
I believe there are free tools as well that can do this stuff, ask google
it used to be the case that free uml tools sucked terribly (am a fan of ea, just don't have clients that want uml), but it may have changed. will look.
1

Caveat: this is an unresearched answer as I haven't had any experience with it myself.

I think you might have some luck with a mocking framework designed for unit testing. An example of such a framework is: cmock

The project page suggests it will generate code from a header. You could then take the code and tweak it.

1 Comment

that's an interesting idea, thanks. i'm currently in the middle of battling with cpp just to get the header in the format i want, but will think more about this approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.