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.

Thursday, January 17, 2013

Few tricks for the GVIM diff mode

Couple of useful tricks for the GVIM diff mode (~/.gvimrc):

- Equalize the diff file window sizes when resizing the GVIM window. That is probably applicable to console vim too, but I generally diff with the GUI vim. (The "Trailing characters" error from :exec occasionally drives me up the wall. But I have finally found out how to properly trigger keyboard shortcut!)

- Toggle font size very very small/very small and small on F5 (font names below are for *nix).

The Doom1-styled toggles I wanted to try already for a long time. In VIM the need for toggles isn't that high since the boolean parameters can be already toggled (:set hls! or :set wrap! for example). I found no other (readable) way to implement them but with functions - one function per state of toggle. A function which is part part of the toggle group does two things: first it sets parameter(s) it needs to set, then it map the toggle shortcut to the next function in the toggle group. To "initialize" the toggle group, simply call one of the functions.


if &diff
        " equalize size of diffed file windows
        au VimResized * :execute "normal! \<C-W>="

        " toggle diff font
        function! DiffSmallFont1()
                set guifont=-misc-fixed-medium-r-normal--9-90-75-75-c-60-iso10646-1
                map :call DiffSmallFont2()<CR>
        endfunction
        function! DiffSmallFont2()
                set guifont=-misc-fixed-medium-r-normal--10-100-75-75-c-60-iso10646-1
                map <F5> :call DiffSmallFont3()<CR>
        endfunction
        function! DiffSmallFont3()
                set guifont=-misc-fixed-medium-r-normal--13-120-75-75-c-70-iso10646-1
                map <F5> :call DiffSmallFont1()<CR>
        endfunction
        call DiffSmallFont2()
endif