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.


Thursday, April 19, 2012

Faking watch on OS X

Sometimes watching something change over time in your terminal is kinda helpful. Linux has a great utility for this called "watch". OS X doesn't some with this. Of course you can build it yourself if you want .. but that can mean a chunk of pain too... luckily bash comes with what you need. "while" and some ANSII escape sequences are enough to get you going.

Here was my first try:

The first problem with this for me was that in iterm2 clear just keeps adding to your terminal scrollback in some weird way. Luckily replacing this with some ANSII control sequences fixes that up nicely.

Now it doesn't add to the scrollback but it does blink every 4 second. I fixed this by storing the current and previous results in temp files and only clearing if they've changed.

Saturday, March 24, 2012

Farewell Tim


It has been just over two weeks since my little brother Tim was killed. He was hit by a drunk driver while cycling - training for the Ride For Youth, a charity ride raising money for young people at risk of self harm or suicide.

The ride for youth requires serious dedication from those participating, riding 640km over 5 days. They are expected to train with the team at least 3 days a week for 6 months. In the week before his death Tim rode over 400km. My Dad has been doing the ride for several years, and this year was going to be his last and Tim's first. Tim was athletic all his life, but with this training he was fitter than he'd ever been.

Tim had an amazing group of friends. He touched so many lives. We've had messages of sympathy and support from all over the world. We estimate somewhere between 700 and 1000 people attended his funeral. Through his studies and work as Chemical Engineer he lived all over the world: Perth, Brisbane, Dubai, Wales, Switzerland and more. Everywhere he went he made great lifelong friends. To Tim everyone was a potential friend.

Tim was also intelligent. He had left his work to pursue a Masters degree in Chemical Engineering, and was considering upgrading that to a Ph.D. Amazingly Tim was using many of the tools I'd studied in my Ph.D. and post-doc. In the last year we'd had conversations about such esoteric topics as "Convergence and Stability of Finite Element Methods."

Finally, Tim was an amazing uncle to my daughter Kira, and my son Grant. Even after a training ride of 140km Tim would still have the energy to run around the table with Kira playing chasey. He'd leave the social events early to take Kira to the beach. Kira is going to miss him terribly, and I'm so sad that Grant will never get to know him. I was so looking forward to Tim teaching them both things like surfing and basket ball. (Both of which I'm useless at.)



If you want to support Tim's cause, don't send us flowers, donate here:
http://www.rideforyouth.com.au/riders/enjo/tim-anderson

Some further information about Tim and the accident can be found here:
www.facebook.com/remembertimbo


I don't know what else to say except

Goodbye Tim,
We're really going to miss you.

Friday, March 2, 2012

Installing node.js on OS X 10.5

The binary distributions of node.js no longer work on 10.5 (at least no distribution I could find.). So I went about building my own from source. There's several pitfalls I had to overcome, so I figured I'd list the solutions here.

Step 1. Download the source. I did this using:

git clone git://github.com/joyent/node.git
git checkout origin/v0.6.11-release

Step 2. Patch the included v8 source. If you dont patch it you get an error about missing symbols for Dictionary::SlowReverseLookup, although they may be mangled, so it's not to obvious.

diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 88ebbf4..c4aea1c 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -10012,6 +10012,9 @@ template Object* Dictionary::
 template Object* Dictionary::SlowReverseLookup(
     Object*);
 
+template Object* Dictionary::SlowReverseLookup(
+    Object*);
+
 template void Dictionary::CopyKeysTo(
     FixedArray*,
     PropertyAttributes,

Step 3. Download a new version of openssl and build and install shared versions. I downloaded version 0.9.8t and built it using:

./config shared
make
make install
On OS X by default this installs to /usr/local/ssl If you try to use the default version of openssl then you get a bunch of errors:
../src/node_crypto.cc: In member function ‘bool node::crypto::DiffieHellman::Init(int)’: 
../src/node_crypto.cc:3537: error: ‘DH_generate_parameters_ex’ was not declared in this scope 
../src/node_crypto.cc: In static member function ‘static v8::Handle node::crypto::DiffieHellman::ComputeSecret(const v8::Arguments&)’: 
../src/node_crypto.cc:3811: error: ‘DH_check_pub_key’ was not declared in this scope 
../src/node_crypto.cc:3814: error: ‘DH_CHECK_PUBKEY_TOO_SMALL’ was not declared in this scope 
../src/node_crypto.cc:3817: error: ‘DH_CHECK_PUBKEY_TOO_LARGE’ was not declared in this scope 
If you forget to build a shared version then node will almost compile, but complain about missing symbols at link time for the final binary.

Step 4. Build node using the changes you've made:

./configure --openssl-includes=/usr/local/ssl/include/ --openssl-libpath=/usr/local/ssl/lib/
make
make install

Now hopefully you'll have a running version of node installed.

Thursday, February 9, 2012

Javascript objects are not hashes

I've some across several posts from people warning about using objects as maps( [1], [2] ), and while they're right I think they miss an important feature. Objects are not hashes. Instead they try to show you how to use them like objects.

The key to the whole issue is the difference in behavior of in and hasOwnProperty.

For example if I want to set a property in an object using a user supplied string I would do this:

This makes it clear that assigning & updating a field is a ternary (append/update/fail) rather than a binary issue (append/update).

If you're feeling paranoid about already broken data, then you might change the use of posts.hasOwnProperty to Object.prototype.hasOwnProperty.call(posts,slug). But this code should prevent hasOwnProperty from getting overwritten in the first place.