Thursday, January 24, 2013

[off-topic] split/filter C++ class declarations from source into header file

Occasionally, I end up writing a simple one-file prototype for the whatever future C++ thingy I'm doing at the moment. Occasionally, the prototype ends up being pretty big and un-prototyle-like a really working program.

For many years now, the most painful part, if prototype was successful, was to make out of it something looking more like a real source code, suitable for integration with the rest of the project.

Namely: move class declarations to a header file. This often ends up being very very mundane task, especially if the prototype was to test some elaborate data model.

Literally ages into the C++ and ages into the *NIX, it downed on me that sed has a trick for it. If source is properly formatted and the main problem is the move of class declarations, then sed's /begin_re/,/end_re/ should work fine. And it does indeed.

$ sed '/^\(struct\|class\)/,/^}/p; d' < prototype.cc > realthing.h
$ sed '/^\(struct\|class\)/,/^}/d;' < prototype.cc > realthing.cc


Basically, sed is told to take from the input the blocks surrounded by struct or class and closing curly bracket (both in first column). For the header we 'p'rint the blocks and 'd'elete the rest, while for the source file we do the opposite (print is the default action of sed, thus no 'p' in the second command). The test with diff should show no differences (I don't like losing lines in the un-checked-in source so I always double check):

$ diff -wu <(sort < prototype.cc) \
     <(cat realthing.h realthing.cc | sort) | less


P.S. That of course does nothing to typedefs and forward declarations, but those are peanuts compared to the declaration of classes. And anyway, I try to put both typedefs and forward declarations into a struct or class just to give them common namespace prefix.

No comments: