#!/usr/bin/env perl # logify.pl ############ # Converts an Objective-C header file (or anything containing a @interface and method definitions) #+into a Logos input file which causes all function calls to be logged. # # Accepts input on stdin or via filename specified on the commandline. # Lines are only processed if we were in an @interface, so you can run this on a file containing # an @implementation, as well. use strict; use FindBin; use lib "$FindBin::Bin/lib"; use Logos::Method; use Logos::Util; $Logos::Util::errorhandler = sub { die "$ARGV:$.: error: missing closing parenthesis$/" }; my $interface = 0; while(my $line = <>) { if($line =~ m/^[+-]\s*\((.*?)\).*?(?=;)/ && $interface == 1) { print logLineForDeclaration($&); } elsif($line =~ m/^\s*\@property\s*\((.*?)\)\s*(.*?)\b([\$a-zA-Z_][\$_a-zA-Z0-9]*)(?=;)/ && $interface == 1) { my @attributes = smartSplit(qr/\s*,\s*/, $1); my $propertyName = $3; my $type = $2; my $readonly = scalar(grep(/readonly/, @attributes)); my %methods = ("setter" => "set".ucfirst($propertyName).":", "getter" => $propertyName); foreach my $attribute (@attributes) { next if($attribute !~ /=/); my @x = smartSplit(qr/\s*=\s*/, $attribute); $methods{$x[0]} = $x[1]; } if($readonly == 0) { print logLineForDeclaration("- (void)".$methods{"setter"}."($type)$propertyName"); } print logLineForDeclaration("- ($type)".$methods{"getter"}); } elsif($line =~ m/^\@interface\s+(.*?)\s*[:(]/ && $interface == 0) { print "%hook $1\n"; $interface = 1; } elsif($line =~ m/^\@end/ && $interface == 1) { print "%end\n"; $interface = 0; } } sub logLineForDeclaration { my $declaration = shift; $declaration =~ m/^[+-]\s*\((.*?)\).*?/; my $rtype = $1; my $innards = "%log; "; if($rtype ne "void") { $innards .= "$rtype r = %orig; "; $innards .= "HBLogDebug(@\" = ".Logos::Method::formatCharForArgType($rtype)."\", ".Logos::Method::printArgForArgType($rtype, "r")."); " if defined Logos::Method::printArgForArgType($rtype, "r"); $innards .= "return r; "; } else { $innards .= "%orig; "; } return "$declaration { $innards}\n"; }