PageRenderTime 19ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/core/externals/update-engine/externals/google-toolbox-for-mac/DebugUtils/GTMMethodCheck.h

http://macfuse.googlecode.com/
C++ Header | 88 lines | 26 code | 12 blank | 50 comment | 3 complexity | 56976052a9f8891f7b224195ca520791 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0
  1. //
  2. // GTMMethodCheck.h
  3. //
  4. // Copyright 2006-2008 Google Inc.
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7. // use this file except in compliance with the License. You may obtain a copy
  8. // of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. // License for the specific language governing permissions and limitations under
  16. // the License.
  17. //
  18. #import <Foundation/Foundation.h>
  19. #import <stdio.h>
  20. #import <sysexits.h>
  21. /// A macro for enforcing debug time checks to make sure all required methods are linked in
  22. //
  23. // When using categories, it can be very easy to forget to include the
  24. // implementation of a category.
  25. // Let's say you had a class foo that depended on method bar of class baz, and
  26. // method bar was implemented as a member of a category.
  27. // You could add the following code:
  28. // @implementation foo
  29. // GTM_METHOD_CHECK(baz, bar)
  30. // @end
  31. // and the code would check to make sure baz was implemented just before main
  32. // was called. This works for both dynamic libraries, and executables.
  33. //
  34. // Classes (or one of their superclasses) being checked must conform to the
  35. // NSObject protocol. We will check this, and spit out a warning if a class does
  36. // not conform to NSObject.
  37. //
  38. // This is not compiled into release builds.
  39. #ifdef DEBUG
  40. #ifdef __cplusplus
  41. extern "C" {
  42. #endif
  43. // If you get an error for GTMMethodCheckMethodChecker not being defined,
  44. // you need to link in GTMMethodCheck.m. We keep it hidden so that we can have
  45. // it living in several separate images without conflict.
  46. // Functions with the ((constructor)) attribute are called after all +loads
  47. // have been called. See "Initializing Objective-C Classes" in
  48. // http://developer.apple.com/documentation/DeveloperTools/Conceptual/DynamicLibraries/Articles/DynamicLibraryDesignGuidelines.html#//apple_ref/doc/uid/TP40002013-DontLinkElementID_20
  49. __attribute__ ((constructor, visibility("hidden"))) void GTMMethodCheckMethodChecker(void);
  50. #ifdef __cplusplus
  51. };
  52. #endif
  53. // This is the "magic".
  54. // A) we need a multi layer define here so that the stupid preprocessor
  55. // expands __LINE__ out the way we want it. We need LINE so that each of
  56. // out GTM_METHOD_CHECKs generates a unique class method for the class.
  57. #define GTM_METHOD_CHECK(class, method) GTM_METHOD_CHECK_INNER(class, method, __LINE__)
  58. #define GTM_METHOD_CHECK_INNER(class, method, line) GTM_METHOD_CHECK_INNER_INNER(class, method, line)
  59. // B) Create up a class method called xxGMethodCheckMethod+class+line that the
  60. // GTMMethodCheckMethodChecker function can look for and call. We
  61. // look for GTMMethodCheckMethodChecker to enforce linkage of
  62. // GTMMethodCheck.m.
  63. #define GTM_METHOD_CHECK_INNER_INNER(class, method, line) \
  64. + (void)xxGTMMethodCheckMethod ## class ## line { \
  65. void (*addr)() = GTMMethodCheckMethodChecker; \
  66. if (addr && ![class instancesRespondToSelector:@selector(method)] \
  67. && ![class respondsToSelector:@selector(method)]) { \
  68. fprintf(stderr, "%s:%d: error: We need method '%s' to be linked in for class '%s'\n", \
  69. __FILE__, line, #method, #class); \
  70. exit(EX_SOFTWARE); \
  71. } \
  72. }
  73. #else // !DEBUG
  74. // Do nothing in release.
  75. #define GTM_METHOD_CHECK(class, method)
  76. #endif // DEBUG