windows-nt/Source/XPSP1/NT/sdktools/trace/tracewpp/fieldtable.h
2020-09-26 16:20:57 +08:00

165 lines
5.1 KiB
C++

/*++
Copyright (c) 1997-2000 Microsoft Corporation
Module Name:
FieldTable.h
Abstract:
Field Table declarations for tracewpp.exe
field table allows tpl interpreter to
work with data collected by during scanning of the source files.
Author:
Gor Nishanov (gorn) 03-Apr-1999
Revision History:
Gor Nishanov (gorn) 03-Apr-1999 -- hacked together to prove that this can work
ToDo:
Clean it up
--*/
extern LPCSTR FieldNames[];
struct FieldHolder;
struct Enumerator {
virtual void Reset(std::string Filter) = 0;
virtual void Next(std::string Filter) = 0;
virtual bool Valid() const = 0;
virtual const FieldHolder* GetData() const = 0;
virtual ~Enumerator(){}
};
struct FieldHolder {
virtual DWORD PrintField(int fieldId, FILE* f, const Enumerator **) const = 0;
virtual BOOL Hidden(std::string filter="") const { return FALSE; }
};
struct VectorPtrTag {};
struct VectorTag {};
struct MapTag{};
struct MapPtrTag{};
template <class T> const FieldHolder* GetFieldHolder(const T& Data, VectorPtrTag) { return Data;}
template <class T> const FieldHolder* GetFieldHolder(const T& Data, VectorTag) { return &Data;}
template <class T> const FieldHolder* GetFieldHolder(const T& Data, MapPtrTag) { return Data.second;}
template <class T> const FieldHolder* GetFieldHolder(const T& Data, MapTag) { return &Data.second;}
template <class Container, class Tag>
class EnumeratorFromContainer : public Enumerator
{
typedef Container::const_iterator const_iterator;
const_iterator _current, _begin, _end;
public:
EnumeratorFromContainer(const Container& v):
_begin(v.begin()),_end(v.end()),_current(v.begin()) {}
void Reset(std::string Filter) { _current = _begin; while(Valid() && GetData()->Hidden(Filter)) ++_current;}
void Next(std::string Filter) { ++_current; while(Valid() && GetData()->Hidden(Filter)) ++_current; }
bool Valid() const { return _current != _end; }
const FieldHolder* GetData() const { return GetFieldHolder(*_current, Tag()); }
};
template <class Container, class Tag>
Enumerator* GetEnumFromContainer(const Container& v, Tag) {
return new EnumeratorFromContainer< Container, Tag >( v );
}
#define DEFAULT_FID 0
#define TEXT_FIELD(FieldId) break; case fid_ ## FieldId: \
if (__f__ == 0) { \
printf("%s.%s can not be enumerated\n",__Object__, #FieldId); \
exit(1); \
}
#define ENUM_FIELD(FieldId,FieldName,Tag) break; case fid_ ## FieldId: \
if (__pEnum__ == 0) { \
printf("%s.%s is an enumeration\n",__Object__, #FieldId); \
exit(1); \
} \
*__pEnum__ = GetEnumFromContainer(FieldName, Tag() );
#define DEFAULT_TEXT_FIELD break; case DEFAULT_FID: \
if (__f__ == 0) {printf("%s can not be enumerated\n",__Object__); exit(1);}
#define DEFAULT_ENUM_FIELD(EnumName,Tag) break; case DEFAULT_FID: \
if (__pEnum__ == 0) {printf("%s is an enumeration\n",__Object__); exit(1);} \
*__pEnum__ = GetEnumFromContainer(EnumName, Tag() );
#define BEGIN_FIELD_TABLE(__ObjectName__, __Output__) \
DWORD PrintField(int __FieldId__, FILE* __Output__, const Enumerator** __pEnum__) const \
{ \
DWORD __status__ = ERROR_SUCCESS; \
static char* __Object__ = #__ObjectName__; \
FILE* __f__ = __Output__; \
UNREFERENCED_PARAMETER(__pEnum__); \
switch(__FieldId__) { case -1:;
#define BEGIN_FIELD_TABLE_NONAME(__Output__) \
DWORD PrintField(int __FieldId__, FILE* __Output__, const Enumerator** __pEnum__) const \
{ \
DWORD __status__ = ERROR_SUCCESS; \
FILE* __f__ = __Output__; \
UNREFERENCED_PARAMETER(__pEnum__); \
switch(__FieldId__) { case -1:;
#define END_FIELD_TABLE \
break;\
default: __status__ = ERROR_NOT_FOUND; \
ReportError("\"%s\" (%d) is not a member of \"%s\"\n",FieldNames[__FieldId__], __FieldId__,__Object__); \
exit(1); \
} \
return __status__; \
}
template <class Container, class Tag>
class ContainerAdapter : public FieldHolder {
LPCSTR __Object__; // END_FIELD_TABLE uses __Object__ as an object name //
Container& _container;
public:
ContainerAdapter(LPCSTR name, Container& container):
_container(container), __Object__(name) {}
BEGIN_FIELD_TABLE_NONAME(out)
TEXT_FIELD(Count) fprintf(out, "%d", _container.size());
DEFAULT_ENUM_FIELD(_container, Tag)
END_FIELD_TABLE
};
class StringAdapter : public FieldHolder {
LPCSTR __Object__; // END_FIELD_TABLE uses __Object__ as an object name //
const std::string& _string;
public:
StringAdapter(LPCSTR name, const std::string& string):
__Object__(name), _string(string) {}
BEGIN_FIELD_TABLE_NONAME(out)
DEFAULT_TEXT_FIELD { fprintf(out, "%s", _string.c_str()); }
END_FIELD_TABLE
};
template<class Iterator>
struct IteratorAdapter : FieldHolder {
Iterator* theRealThing;
explicit IteratorAdapter(Iterator* aRealThing):theRealThing(aRealThing) {}
DWORD PrintField(int fieldId, FILE* f, const Enumerator** pEnum) const {
return (*theRealThing)->PrintField(fieldId, f, pEnum);
}
};