Simple “method got called” debugging

February 26th, 2009

For quick and dirty project debugging, I often find myself using code like:

- (void)someRandomMethod
{
NSLog(@"-someRandomMethod called");
// ...
}

Playing around with precompiled headers in XCode, it occurred to me there’s a much neater way to do this. In the precompiled header (XCode probably created a .pch file for you) add:

#define HELLO NSLog(@"-----TRACE----- %s (%s:%d)", __PRETTY_FUNTION__, __FILE__, __LINE__);

Then in any method in your project you can get easy tracing:

- (void)someOtherMethod
{
HELLO
// ...
}

To prevent trace messages ever showing up in release builds, you could wrap the definition in an #ifdef and make the macro effectively a no-op.

Dangerous Shell Scripts

January 13th, 2009

I’ve seen a few shell scripts recently which use environment variables to determine installation paths etc so that the script Just Works when run.

This is generally desirable but the importance of checking the environment variables before doing anything should not be overlooked. Consider the following (admittedly contrived!) example:

#!/usr/bin/env bash

# uninstall product
PRODUCTROOT="${INSTALLROOT}/${PRODUCTNAME}"

rm -rf "${PRODUCTROOT}"

The script assumes INSTALLROOT and PRODUCTNAME are set but it doesn’t verify this. If they’re not, the effective behaviour is:

rm -rf "/"

(Please don’t try that out!)

While it’s not possible for a deletion script to really know whether or not you meant to delete something, it can at least check the preconditions.

To check that the necessary variables are set:

#!/usr/bin/env bash

function check_env_vars() {
  local var_list=$@
  for var_name in ${var_list[@]}; do
    eval var_value="\$$var_name"
    if [ -z "${var_value}" ]; then
      echo "${var_name} must be set!" >&2
      exit 1
    fi
  done
}

check_env_vars INSTALLROOT PRODUCTNAME

# if we get this far, the variables are set
# you could change the exit to return an error status
# instead and trap it here

Tracing Objective-C method calls

January 2nd, 2009

There are probably more clever ways to do this, but as a quick and dirty hack I find this useful for finding out which methods are being, or could potentially be, called on my object:

- (BOOL)respondsToSelector:(SEL)aSelector
{
  NSLog(@"respondsToSelector:'%s'", sel_getName(aSelector));
  return [super respondsToSelector:aSelector];
}

Compiling connect.c on Solaris 10

May 7th, 2008

I mentioned connect.c for SOCKS proxy connections. Compiling it on Solaris 10 is relatively straightforward but you need to define INADDR_NONE as it’s not present in the system headers.

gcc -DINADDR_NONE='((unsigned long)-1)' connect.c -o connect \
-lnsl -lsocket -lresolv

You also need to link it with libnsl, libsocket and libresolv.

Getting Trang Working

April 19th, 2008

I’m working with an application which requires Trang to convert RELAX NG schema files. Trang itself is quite old code and this seems to present problems on newer distributions - all sorts of problems getting it to run under GCJ in particular.

While there are probably speed advantages in going the GCJ route, I’m more interested in just getting it working - the schema files only need converting once so speed isn’t really an issue here.

I cheated and just used the JDK and a shell script wrapper. If you just need it to work too, here’s how I did it.

Install JDK

This is obviously different for every platform, but in this case it’s on Ubuntu and is as simple as:

sudo aptitude install sun-java5-jdk
Fetch Trang

You need the original Java zip file, not the GCJ version.

wget [http://www.thaiopensource.com/download/trang-20030619.zip]

From this you need to extract the jar file:

unzip -j trang-20030619.zip '*/trang.jar'

Install Trang

I placed mine in /usr/local/trang but it doesn’t really matter where it goes.

sudo mkdir /usr/local/trang
sudo cp trang.jar /usr/local/trang

Create a wrapper shell script

The shell script just invokes java on the Trang jar file with the supplied arguments. Create the file /usr/local/bin/trang in your favourite editor:

#!/bin/sh
/usr/lib/jvm/java-1.5.0-sun/bin/java -jar /usr/local/trang/trang.jar $@

And then make the script executable:

sudo chmod +x /usr/local/bin/trang

Test it

Assuming the script is in your PATH, you should now be able to use it as normal (albeit slowly - the startup time hurts a bit!)

trang file.rnc file.rng

Git with and without proxy

April 10th, 2008

I use Git both at home and at work; at home I’ve got a direct connection but at work I must connect through a SOCKS proxy for external access.

Although Git supports proxy configuration, it’s irritating to have to change this all the time depending on my location. Setting the environment variable GIT_PROXY_COMMAND overrides whatever proxy configuration already exists - this is all we need to get git:// repositories to work. To get Git-over-SSH connections to work, which you probably want for push operations, you’ll also need to set up GIT_SSH.

I’ve created some simple shell scripts to help. The first is a simple wrapper for connect.c (which you may need to compile, of course).

#!/bin/sh
# Filename: ~/bin/socks-gw
# This script connects to a SOCKS proxy using connect.c
/path/to/connect -S my.socks.server:1080 $@

The second is another simple wrapper for SSH through a SOCKS proxy:

#!/bin/sh
# Filename: ~/bin/socks-ssh
# This script opens an SSH connection through a SOCKS server
ssh -o ProxyCommand="${HOME}/bin/socks-gw %h %p" $@

Lastly, I have a script I source when at work to set the environment variables for me:

#!/bin/sh
# Filename: ~/bin/work
# This script sets Git to use the SOCKS proxy
export GIT_SSH="${HOME}/bin/socks-ssh"
export GIT_PROXY_COMMAND="${HOME}/bin/socks-gw"

And I’ve put an alias in my .bash_profile to help me remember to source it instead of running it:

alias work="source ${HOME}/bin/work"

Now when I use Git at home, it just works without having to remove any proxy config, and when I use it at work I just type work in my shell and it works there too…

Hello, World!

March 24th, 2008

I’ve been meaning to install blog or CMS software of some description for a while… You won’t find my life story here - it’s more a place to stick odd useful code snippets and such.