Saturday, October 20, 2012

Finding changes in ugly XML with git and xmllint

This is probably not going to be useful to very many people, but it helped me track down a small bug, and I'm preserving it mostly incase I need something similar later.

So the key issue here is that we have some XML that is stored in git. Unfortunately this generated XML is not nicely formatted. Thus changes in git don't show nicely using git log or git diff.

My technique was this:

  1. Find the commits that changed the file of interest.

    git log --oneline afile.xml | awk '{print $1}'
  2. Get the file at that revision.

    git show $REVISION:afile.xml
  3. Get the file at the previous revision

    git show $REVISION~1:afile.xml
  4. Pass these through xmllint --format to clean them up

  5. diff the cleaned up versions

This sounds pretty complex, but it can be wrapped up into a concise piece of bash script.
Now its not going to work across merges etc, but the general technique can be handy.

I suspect a similar thing may have been obtainable by setting a custom diff tool in git but I couldn't see an easy way to get exactly what I wanted.

Wednesday, October 3, 2012

Partial template specialization for functions in C++

Partial template specialization for functions in C++

The short of it is you can't do it. But you can do something that looks just like it.

What is template specialization?

For functions template specialization looks like this:

So the first template tells us what to do in general and the specialization tells us what to do in particular cases.

What is partial template specialization?

Its just like template specialization, but you're not specifying all the template parameters. So for the example above we might like to add a specialization that prints "Lucky 7" when the first template argument is 7. If we could write it, it would look like this (but its not valid C++)

However this doesn't work - it's not valid C++.

What is the issue?

C++ does not allow function partial specialization.

How do we get around it?

C++ does allow partial template specialization for classes (and structs). So our solution is just to defer to a templated helper class with static functions:

Its verbose, but it works.

NOTE: in this case we're working with `int` parameters that would be better done with a normal function containing a couple of `if` statements - however all this works for type templates too.