165 lines
5.1 KiB
C
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);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|