Re-org
diff --git a/include/catch_objc.hpp b/include/catch_objc.hpp
new file mode 100644
index 0000000..690ce5d
--- /dev/null
+++ b/include/catch_objc.hpp
@@ -0,0 +1,185 @@
+/*
+ * catch_objc.hpp
+ * Catch
+ *
+ * Created by Phil on 14/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+#ifndef TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
+
+#import <objc/runtime.h>
+#include <string>
+
+#include "catch.hpp"
+#include "internal/catch_test_case_info.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// This protocol is really only here for (self) documenting purposes, since
+// all its methods are optional.
+@protocol OcFixture
+
+@optional
+
+-(void) setUp;
+-(void) tearDown;
+
+@end
+
+namespace Catch
+{
+ class OcMethod : public ITestCase
+ {
+ public:
+ ///////////////////////////////////////////////////////////////////////
+ OcMethod
+ (
+ Class cls,
+ SEL sel
+ )
+ : m_cls( cls ),
+ m_sel( sel )
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ virtual void invoke
+ ()
+ const
+ {
+ id obj = class_createInstance( m_cls, 0 );
+ obj = [obj init];
+
+ if( [obj respondsToSelector: @selector(setUp) ] )
+ [obj performSelector: @selector(setUp)];
+
+ if( [obj respondsToSelector: m_sel] )
+ [obj performSelector: m_sel];
+
+ if( [obj respondsToSelector: @selector(tearDown) ] )
+ [obj performSelector: @selector(tearDown)];
+
+ [obj release];
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ virtual ITestCase* clone
+ ()
+ const
+ {
+ return new OcMethod( m_cls, m_sel );
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ virtual bool operator ==
+ (
+ const ITestCase& other
+ )
+ const
+ {
+ const OcMethod* ocmOther = dynamic_cast<const OcMethod*> ( &other );
+ return ocmOther && ocmOther->m_sel == m_sel;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ virtual bool operator <
+ (
+ const ITestCase& other
+ )
+ const
+ {
+ const OcMethod* ocmOther = dynamic_cast<const OcMethod*> ( &other );
+ return ocmOther && ocmOther->m_sel < m_sel;
+ }
+
+ private:
+ Class m_cls;
+ SEL m_sel;
+ };
+
+ namespace Detail
+ {
+
+ ///////////////////////////////////////////////////////////////////////
+ inline bool startsWith
+ (
+ const std::string& str,
+ const std::string& sub
+ )
+ {
+ return str.length() > sub.length() && str.substr( 0, sub.length() ) == sub;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ inline const char* getAnnotation
+ (
+ Class cls,
+ const std::string& annotationName,
+ const std::string& testCaseName
+ )
+ {
+ NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
+ SEL sel = NSSelectorFromString( selStr );
+ [selStr release];
+ if( [cls respondsToSelector: sel] )
+ return (const char*)[cls performSelector: sel];
+ return "";
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ inline size_t registerTestMethods
+ ()
+ {
+ size_t noTestMethods = 0;
+ int noClasses = objc_getClassList( NULL, 0 );
+
+ std::vector<Class> classes( noClasses );
+ objc_getClassList( &classes[0], noClasses );
+
+ for( int c = 0; c < noClasses; c++ )
+ {
+ Class cls = classes[c];
+ {
+ u_int count;
+ Method* methods = class_copyMethodList( cls, &count );
+ for( int m = 0; m < count ; m++ )
+ {
+ SEL selector = method_getName(methods[m]);
+ std::string methodName = sel_getName(selector);
+ if( Detail::startsWith( methodName, "Catch_TestCase_" ) )
+ {
+ std::string testCaseName = methodName.substr( 15 );
+ const char* name = Detail::getAnnotation( cls, "Name", testCaseName );
+ const char* desc = Detail::getAnnotation( cls, "Description", testCaseName );
+
+ Hub::getTestCaseRegistry().registerTest( TestCaseInfo( new OcMethod( cls, selector ), name, desc, "", 0 ) );
+ noTestMethods++;
+
+ }
+ }
+ free(methods);
+ }
+ }
+ return noTestMethods;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#define OC_TEST_CASE( name, desc )\
++(const char*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
+{\
+return name; \
+}\
++(const char*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
+{ \
+return desc; \
+} \
+-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
+
+#endif // TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
\ No newline at end of file