print
def visit_bitmask(self, bitmask):
- print 'static void __traceBitmask%s(%s value) {' % (bitmask.id, bitmask.type)
- print ' Trace::BeginBitmask();'
+ print 'static const Trace::BitmaskVal __bitmask%s_vals[] = {' % (bitmask.id)
for value in bitmask.values:
- print ' if((value & %s) == %s) {' % (value, value)
- print ' Trace::LiteralNamedConstant("%s", %s);' % (value, value)
- print ' value &= ~%s;' % value
- print ' }'
- print ' if(value) {'
- dump_instance(bitmask.type, "value");
- print ' }'
- print ' Trace::EndBitmask();'
- print '}'
+ print ' {"%s", %s},' % (value, value)
+ print '};'
+ print
+ print 'static const Trace::BitmaskSig __bitmask%s_sig = {' % (bitmask.id)
+ print ' %u, %u, __bitmask%s_vals' % (int(bitmask.id), len(bitmask.values), bitmask.id)
+ print '};'
print
def visit_pointer(self, pointer):
print ' __traceEnum%s(%s);' % (enum.id, instance)
def visit_bitmask(self, bitmask, instance):
- print ' __traceBitmask%s(%s);' % (bitmask.id, instance)
+ print ' Trace::LiteralBitmask(__bitmask%s_sig, %s);' % (bitmask.id, instance)
def visit_pointer(self, pointer, instance):
print ' if(%s) {' % instance
visitor.visit(this);
}
+void Bitmask::visit(Visitor &visitor) {
+ visitor.visit(this);
+}
+
void Array::visit(Visitor &visitor) {
visitor.visit(this);
}
os << literal << node->name << normal;
}
+ void visit(Bitmask *bitmask) {
+ unsigned long long value = bitmask->value;
+ const Bitmask::Signature *sig = bitmask->sig;
+ bool first = true;
+ for (Bitmask::Signature::const_iterator it = sig->begin(); value != 0 && it != sig->end(); ++it) {
+ assert(it->second);
+ if ((value & it->second) == it->second) {
+ if (!first) {
+ os << " | ";
+ }
+ os << literal << it->first << normal;
+ value &= ~it->second;
+ first = false;
+ }
+ }
+ if (value || first) {
+ if (!first) {
+ os << " | ";
+ }
+ os << literal << std::hex << value << std::dec << normal;
+ }
+ }
+
void visit(Array *array) {
if (array->values.size() == 1) {
os << "&";
};
+class Bitmask : public UInt
+{
+public:
+ typedef std::pair<std::string, unsigned long long> Pair;
+ typedef std::vector<Pair> Signature;
+
+ Bitmask(const Signature *_sig, unsigned long long _value) : UInt(_value), sig(_sig) {}
+
+ void visit(Visitor &visitor);
+
+ const Signature *sig;
+};
+
+
class Array : public Value
{
public:
virtual void visit(Float *) {assert(0);}
virtual void visit(String *) {assert(0);}
virtual void visit(Const *) {assert(0);}
+ virtual void visit(Bitmask *bitmask) {visit(static_cast<UInt *>(bitmask));}
virtual void visit(Array *) {assert(0);}
virtual void visit(Blob *) {assert(0);}
typedef std::map<unsigned, Call *> callmap;
callmap calls;
+ typedef std::map<size_t, Bitmask::Signature *> BitmaskMap;
+ BitmaskMap bitmasks;
+
unsigned next_call_no;
public:
}
Value *parse_bitmask() {
- unsigned long long value = 0;
- int c;
- do {
- c = read_byte();
- switch(c) {
- case Trace::TYPE_SINT:
- value |= -(signed long long)read_uint();
- break;
- case Trace::TYPE_UINT:
- value |= read_uint();
- break;
- case Trace::TYPE_CONST:
- read_name();
- break;
- case Trace::TYPE_NULL:
- goto done;
- default:
- std::cerr << "error: uexpected type " << c << "\n";
- assert(0);
- return NULL;
- }
- } while(true);
-done:
- return new UInt(value);
+ size_t id = read_uint();
+ Bitmask::Signature *sig;
+ BitmaskMap::const_iterator it = bitmasks.find(id);
+ if (it == bitmasks.end()) {
+ size_t size = read_uint();
+ sig = new Bitmask::Signature(size);
+ for (Bitmask::Signature::iterator it = sig->begin(); it != sig->end(); ++it) {
+ it->first = read_string();
+ it->second = read_uint();
+ assert(it->second);
+ }
+ bitmasks[id] = sig;
+ } else {
+ sig = it->second;
+ }
+ assert(sig);
+
+ unsigned long long value = read_uint();
+
+ return new Bitmask(sig, value);
}
Value *parse_array(void) {
LiteralSInt(value);
}
+static std::map<Id, bool> bitmasks;
+
+void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value) {
+ WriteByte(Trace::TYPE_BITMASK);
+ WriteUInt(bitmask.id);
+ if (!bitmasks[bitmask.id]) {
+ WriteUInt(bitmask.count);
+ for (unsigned i = 0; i < bitmask.count; ++i) {
+ WriteString(bitmask.values[i].name);
+ WriteUInt(bitmask.values[i].value);
+ }
+ bitmasks[bitmask.id] = true;
+ }
+ WriteUInt(value);
+}
+
void LiteralNull(void) {
WriteByte(Trace::TYPE_NULL);
}
*
**************************************************************************/
-#ifndef _TRACE_HPP_
-#define _TRACE_HPP_
+#ifndef _TRACE_WRITE_HPP_
+#define _TRACE_WRITE_HPP_
namespace Trace {
+ typedef unsigned Id;
+
+ struct BitmaskVal {
+ const char *name;
+ unsigned long long value;
+ };
+
+ struct BitmaskSig {
+ Id id;
+ unsigned count;
+ const BitmaskVal *values;
+ };
+
void Open(void);
void Close(void);
void BeginMember(const char *name);
inline void EndMember(void) {}
- void BeginBitmask(void);
- void EndBitmask(void);
-
void LiteralBool(bool value);
void LiteralSInt(signed long long value);
void LiteralUInt(unsigned long long value);
void LiteralWString(const wchar_t *str);
void LiteralBlob(const void *data, size_t size);
void LiteralNamedConstant(const char *name, long long value);
+ void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value);
void LiteralNull(void);
void LiteralOpaque(const void *ptr);
void Abort(void);
}
-#endif /* _TRACE_HPP_ */
+#endif /* _TRACE_WRITE_HPP_ */