enum => NSString

I wish it were possible in C to access an enum’s name in string form given a type and its integer value. It’s great for logging/debugging.

Until that day arrives, here’s a small Ruby script which automates the process of vending an NSString given typed enum value:

def NSStringFromEnum(input)
  inputArray = input.lines.collect
  typeNameLine = inputArray[-1]
  typeName = typeNameLine.match(/(\w+);/)[1]

  output = "NSString* NSStringFrom#{typeName}(#{typeName} value) {\n    switch (value) {\n";

  constantLines = inputArray[1..-2]
  constantLines.each {|constantLine|
    constantName = constantLine.match(/(\w+)/)[1]
    output += "        case #{constantName}:\n";
    output += "            return @\"#{constantName}\";\n";
    output += "            break;\n";
  }
  output += "        default:\n";
  output += "            return [NSString stringWithFormat:@\"<unknown #{typeName}: %d>\", value];\n";

  output + "    }\n}"
end

Example input:

typedef enum {
    JRStream_Disconnected,
    JRStream_Connecting,
    JRStream_Connected,
    JRStream_Disconnecting
}   JRStreamState;

Example output:

NSString* NSStringFromJRStreamState(JRStreamState value) {
    switch (value) {
        case JRStream_Disconnected:
            return @"JRStream_Disconnected";
            break;
        case JRStream_Connecting:
            return @"JRStream_Connecting";
            break;
        case JRStream_Connected:
            return @"JRStream_Connected";
            break;
        case JRStream_Disconnecting:
            return @"JRStream_Disconnecting";
            break;
        default:
            return [NSString stringWithFormat:@"<unknown JRStreamState: %d>", value];
    }
}

Update: Guess I should mention how I use it. I put this script into an Automator Service. Apparently you can also use TextExpander and probably Typinator as well. Finally, Benedict Cohen wrote a C macro version that looks promising.

Update: I extended Benedict Cohen’s excellent work and I’m pleased to offer JREnum.

Dec 8 2012