2012-12-10 8 views
7

Ich möchte leere Implementierungen von Prozeduren in einer Header-Datei definiert generieren. Idealerweise sollten sie NULL für Zeiger, 0 für Ganzzahlen usw. zurückgeben und in einer idealen Welt auch nach stderr drucken, welche Funktion aufgerufen wurde.C-Code automatisch von Header generieren

Die Motivation dafür ist die Notwendigkeit, einen Wrapper zu implementieren, der eine Teilmenge einer komplexen, vorhandenen API (die Header-Datei) an eine andere Bibliothek anpasst. Nur eine kleine Anzahl der Verfahren in der API muss delegiert werden, aber es ist nicht klar, welche. Ich hoffe also, einen iterativen Ansatz zu verwenden, bei dem ich gegen diesen automatisch generierten Wrapper antrete, sehe, was aufgerufen wird, das mit Delegierung implementiere und wiederhole.

Ich habe Automatically generate C++ file from header? gesehen, aber die Antworten scheinen C++ spezifisch zu sein.

Also, für Menschen, die die Frage in einfachen Worten geschrieben haben, wie kann ich die Generierung einer solchen Implementierung angesichts der Header-Datei automatisieren? Ich würde ein existierendes Werkzeug bevorzugen - meine derzeitige beste Schätzung für eine einfache Lösung ist Pycparser.

update Danke Jungs. Beide gute Antworten. Hat auch meinen aktuellen Hack gepostet.

+0

Jetzt haben Sie nicht wirklich eine Frage gestellt, soweit ich sehe, aber ich vermute, Sie fragen nach einem vorhandenen Werkzeug, das das tun kann? Leider kenne ich kein Tool, aber es klingt grundlegend genug, um eine schnelle Python-Implementierung (oder eine andere High-Level-Sprache) durchzuführen, um es zu lösen. – Jite

+0

Ich habe die Frage geklärt. Ja, ich kann ein Programm schreiben, um dies zu tun. aber es ist nicht trivial - es erfordert zum Beispiel einen anständigen Parser. Der Header ist groß genug und komplex genug, dass ein Ad-hoc-Regexp-basierter Kludi ein zeitraubendes Chaos sein wird. –

+0

Hallo, muss der Prozess leicht wiederholbar sein? Möchten Sie beispielsweise die Stub-Implementierung aktualisieren können, wenn neue Versionen der API veröffentlicht werden? – OlduwanSteve

Antwort

1

UML-Modellierungstools können eine Standardimplementierung in der Sprache Ihrer Wahl generieren. Im Allgemeinen gibt es auch eine Unterstützung für das Importieren von Quellcode (einschließlich C-Header). Sie können versuchen, Ihre Header zu importieren und Quellcode daraus zu generieren. Ich persönlich habe Erfahrung mit Enterprise Architect und es unterstützt beide dieser Operationen.

+0

ah ja, ea würde das wahrscheinlich tun (wenn auch nicht die Print-Statements). obwohl vielleicht nur in der kostenpflichtigen Version, und ich hatte jahrelang keine Lizenz. werde es überprüfen. Vielen Dank. –

+0

Ich glaube, es gibt auch kostenlose Tools, die dieses Zeug tun können, fragen google – SomeWittyUsername

+0

es war einmal der Fall, dass kostenlose UML-Tools schrecklich saugt (bin ein Fan von ea, nur nicht Kunden, die uml wollen), aber es kann sich geändert haben. aussehen wird. –

1

Vorbehalt: Dies ist eine unerforschte Antwort, da ich selbst keine Erfahrung damit hatte.

Ich denke, dass Sie etwas Glück mit einem spottenden Rahmen haben könnten, der für Komponententests entworfen ist. Ein Beispiel für ein solches Framework ist: cmock

Die Projektseite schlägt vor, dass Code aus einer Kopfzeile generiert wird. Sie könnten dann den Code nehmen und zwicken.

+0

das ist eine interessante Idee, danke. Ich bin gerade mitten im Kampf mit cpp, nur um den Header in dem Format zu bekommen, das ich will, aber werde mehr über diesen Ansatz nachdenken. –

2

Also, ich werde den ea Vorschlag als die "Antwort" markieren, weil ich denke, es ist wahrscheinlich die beste Idee im Allgemeinen. obwohl ich denke, dass der cmock-vorschlag sehr gut im tdd-ansatz funktionieren würde, wo die bibliotheksentwicklung durch testfehler vorangetrieben wurde, und am Ende könnte ich das versuchen. aber jetzt brauche ich einen schnelleren und dreckigeren ansatz, der interaktiv funktioniert (die fragliche library ist ein dynamisch geladenes plugin für ein anderes, interaktives programm und ich versuche, die reihenfolge der api-anrufe zu rekonstruieren ...)

Also was ich getan habe, war ein Python-Skript zu schreiben, das pycarse aufruft. Ich werde es hier für den Fall einschließen, dass es anderen hilft, aber es ist überhaupt nicht allgemein (nimmt an, dass alle Funktionen zum Beispiel int zurückgeben und einen Hack haben, um func defs in typedefs zu vermeiden).

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)