Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
5.1 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. FieldTable.h
  5. Abstract:
  6. Field Table declarations for tracewpp.exe
  7. field table allows tpl interpreter to
  8. work with data collected by during scanning of the source files.
  9. Author:
  10. Gor Nishanov (gorn) 03-Apr-1999
  11. Revision History:
  12. Gor Nishanov (gorn) 03-Apr-1999 -- hacked together to prove that this can work
  13. ToDo:
  14. Clean it up
  15. --*/
  16. extern LPCSTR FieldNames[];
  17. struct FieldHolder;
  18. struct Enumerator {
  19. virtual void Reset(std::string Filter) = 0;
  20. virtual void Next(std::string Filter) = 0;
  21. virtual bool Valid() const = 0;
  22. virtual const FieldHolder* GetData() const = 0;
  23. virtual ~Enumerator(){}
  24. };
  25. struct FieldHolder {
  26. virtual DWORD PrintField(int fieldId, FILE* f, const Enumerator **) const = 0;
  27. virtual BOOL Hidden(std::string filter="") const { return FALSE; }
  28. };
  29. struct VectorPtrTag {};
  30. struct VectorTag {};
  31. struct MapTag{};
  32. struct MapPtrTag{};
  33. template <class T> const FieldHolder* GetFieldHolder(const T& Data, VectorPtrTag) { return Data;}
  34. template <class T> const FieldHolder* GetFieldHolder(const T& Data, VectorTag) { return &Data;}
  35. template <class T> const FieldHolder* GetFieldHolder(const T& Data, MapPtrTag) { return Data.second;}
  36. template <class T> const FieldHolder* GetFieldHolder(const T& Data, MapTag) { return &Data.second;}
  37. template <class Container, class Tag>
  38. class EnumeratorFromContainer : public Enumerator
  39. {
  40. typedef Container::const_iterator const_iterator;
  41. const_iterator _current, _begin, _end;
  42. public:
  43. EnumeratorFromContainer(const Container& v):
  44. _begin(v.begin()),_end(v.end()),_current(v.begin()) {}
  45. void Reset(std::string Filter) { _current = _begin; while(Valid() && GetData()->Hidden(Filter)) ++_current;}
  46. void Next(std::string Filter) { ++_current; while(Valid() && GetData()->Hidden(Filter)) ++_current; }
  47. bool Valid() const { return _current != _end; }
  48. const FieldHolder* GetData() const { return GetFieldHolder(*_current, Tag()); }
  49. };
  50. template <class Container, class Tag>
  51. Enumerator* GetEnumFromContainer(const Container& v, Tag) {
  52. return new EnumeratorFromContainer< Container, Tag >( v );
  53. }
  54. #define DEFAULT_FID 0
  55. #define TEXT_FIELD(FieldId) break; case fid_ ## FieldId: \
  56. if (__f__ == 0) { \
  57. printf("%s.%s can not be enumerated\n",__Object__, #FieldId); \
  58. exit(1); \
  59. }
  60. #define ENUM_FIELD(FieldId,FieldName,Tag) break; case fid_ ## FieldId: \
  61. if (__pEnum__ == 0) { \
  62. printf("%s.%s is an enumeration\n",__Object__, #FieldId); \
  63. exit(1); \
  64. } \
  65. *__pEnum__ = GetEnumFromContainer(FieldName, Tag() );
  66. #define DEFAULT_TEXT_FIELD break; case DEFAULT_FID: \
  67. if (__f__ == 0) {printf("%s can not be enumerated\n",__Object__); exit(1);}
  68. #define DEFAULT_ENUM_FIELD(EnumName,Tag) break; case DEFAULT_FID: \
  69. if (__pEnum__ == 0) {printf("%s is an enumeration\n",__Object__); exit(1);} \
  70. *__pEnum__ = GetEnumFromContainer(EnumName, Tag() );
  71. #define BEGIN_FIELD_TABLE(__ObjectName__, __Output__) \
  72. DWORD PrintField(int __FieldId__, FILE* __Output__, const Enumerator** __pEnum__) const \
  73. { \
  74. DWORD __status__ = ERROR_SUCCESS; \
  75. static char* __Object__ = #__ObjectName__; \
  76. FILE* __f__ = __Output__; \
  77. UNREFERENCED_PARAMETER(__pEnum__); \
  78. switch(__FieldId__) { case -1:;
  79. #define BEGIN_FIELD_TABLE_NONAME(__Output__) \
  80. DWORD PrintField(int __FieldId__, FILE* __Output__, const Enumerator** __pEnum__) const \
  81. { \
  82. DWORD __status__ = ERROR_SUCCESS; \
  83. FILE* __f__ = __Output__; \
  84. UNREFERENCED_PARAMETER(__pEnum__); \
  85. switch(__FieldId__) { case -1:;
  86. #define END_FIELD_TABLE \
  87. break;\
  88. default: __status__ = ERROR_NOT_FOUND; \
  89. ReportError("\"%s\" (%d) is not a member of \"%s\"\n",FieldNames[__FieldId__], __FieldId__,__Object__); \
  90. exit(1); \
  91. } \
  92. return __status__; \
  93. }
  94. template <class Container, class Tag>
  95. class ContainerAdapter : public FieldHolder {
  96. LPCSTR __Object__; // END_FIELD_TABLE uses __Object__ as an object name //
  97. Container& _container;
  98. public:
  99. ContainerAdapter(LPCSTR name, Container& container):
  100. _container(container), __Object__(name) {}
  101. BEGIN_FIELD_TABLE_NONAME(out)
  102. TEXT_FIELD(Count) fprintf(out, "%d", _container.size());
  103. DEFAULT_ENUM_FIELD(_container, Tag)
  104. END_FIELD_TABLE
  105. };
  106. class StringAdapter : public FieldHolder {
  107. LPCSTR __Object__; // END_FIELD_TABLE uses __Object__ as an object name //
  108. const std::string& _string;
  109. public:
  110. StringAdapter(LPCSTR name, const std::string& string):
  111. __Object__(name), _string(string) {}
  112. BEGIN_FIELD_TABLE_NONAME(out)
  113. DEFAULT_TEXT_FIELD { fprintf(out, "%s", _string.c_str()); }
  114. END_FIELD_TABLE
  115. };
  116. template<class Iterator>
  117. struct IteratorAdapter : FieldHolder {
  118. Iterator* theRealThing;
  119. explicit IteratorAdapter(Iterator* aRealThing):theRealThing(aRealThing) {}
  120. DWORD PrintField(int fieldId, FILE* f, const Enumerator** pEnum) const {
  121. return (*theRealThing)->PrintField(fieldId, f, pEnum);
  122. }
  123. };