fprintf(out, "}\n");
}
-//
-// Functions used when generating QMetaObject directly
-//
-// Much of this code is copied from the corresponding
-// C++ code-generating functions; we can change the
-// two generators so that more of the code is shared.
-// The key difference from the C++ code generator is
-// that instead of calling fprintf(), we append bytes
-// to a buffer.
-//
-
-QMetaObject *Generator::generateMetaObject(bool ignoreProperties)
-{
-//
-// build the data array
-//
-
- // filter out undeclared enumerators and sets
- {
- QList<EnumDef> enumList;
- for (int i = 0; i < cdef->enumList.count(); ++i) {
- EnumDef def = cdef->enumList.at(i);
- if (cdef->enumDeclarations.contains(def.name)) {
- enumList += def;
- }
- QByteArray alias = cdef->flagAliases.value(def.name);
- if (cdef->enumDeclarations.contains(alias)) {
- def.name = alias;
- enumList += def;
- }
- }
- cdef->enumList = enumList;
- }
-
- int index = 10;
- meta_data
- << 1 // revision
- << strreg(cdef->qualified) // classname
- << cdef->classInfoList.count() << (cdef->classInfoList.count() ? index : 0) // classinfo
- ;
- index += cdef->classInfoList.count() * 2;
-
- int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count();
- meta_data << methodCount << (methodCount ? index : 0); // methods
- index += methodCount * 5;
- if (!ignoreProperties) {
- meta_data << cdef->propertyList.count() << (cdef->propertyList.count() ? index : 0); // properties
- index += cdef->propertyList.count() * 3;
- } else {
- meta_data << 0 << 0; // properties
- }
- meta_data << cdef->enumList.count() << (cdef->enumList.count() ? index : 0); // enums/sets
-
-//
-// Build classinfo array
-//
- _generateClassInfos();
-
-//
-// Build signals array first, otherwise the signal indices would be wrong
-//
- _generateFunctions(cdef->signalList, MethodSignal);
-
-//
-// Build slots array
-//
- _generateFunctions(cdef->slotList, MethodSlot);
-
-//
-// Build method array
-//
- _generateFunctions(cdef->methodList, MethodMethod);
-
-
-//
-// Build property array
-//
- if (!ignoreProperties)
- _generateProperties();
-
-//
-// Build enums array
-//
- _generateEnums(index);
-
-//
-// Terminate data array
-//
- meta_data << 0;
-
-//
-// Build stringdata array
-//
- QVector<char> string_data;
- for (int i = 0; i < strings.size(); ++i) {
- const char *s = strings.at(i).constData();
- char c;
- do {
- c = *(s++);
- string_data << c;
- } while (c != '\0');
- }
-
-//
-// Finally create and initialize the static meta object
-//
- const int meta_object_offset = 0;
- const int meta_object_size = sizeof(QMetaObject);
- const int meta_data_offset = meta_object_offset + meta_object_size;
- const int meta_data_size = meta_data.count() * sizeof(uint);
- const int string_data_offset = meta_data_offset + meta_data_size;
- const int string_data_size = string_data.count();
- const int total_size = string_data_offset + string_data_size;
-
- char *blob = new char[total_size];
-
- char *string_data_output = blob + string_data_offset;
- const char *string_data_src = string_data.constData();
- for (int i = 0; i < string_data.count(); ++i)
- string_data_output[i] = string_data_src[i];
-
- uint *meta_data_output = reinterpret_cast<uint *>(blob + meta_data_offset);
- const uint *meta_data_src = meta_data.constData();
- for (int i = 0; i < meta_data.count(); ++i)
- meta_data_output[i] = meta_data_src[i];
-
- QMetaObject *meta_object = new (blob + meta_object_offset)QMetaObject;
- meta_object->d.superdata = 0;
- meta_object->d.stringdata = string_data_output;
- meta_object->d.data = meta_data_output;
- meta_object->d.extradata = 0;
- return meta_object;
-}
-
-void Generator::_generateClassInfos()
-{
- for (int i = 0; i < cdef->classInfoList.size(); ++i) {
- const ClassInfoDef &c = cdef->classInfoList.at(i);
- meta_data << strreg(c.name) << strreg(c.value);
- }
-}
-
-void Generator::_generateFunctions(QList<FunctionDef> &list, int type)
-{
- for (int i = 0; i < list.count(); ++i) {
- const FunctionDef &f = list.at(i);
-
- QByteArray sig = f.name + '(';
- QByteArray arguments;
-
- for (int j = 0; j < f.arguments.count(); ++j) {
- const ArgumentDef &a = f.arguments.at(j);
- if (j) {
- sig += ',';
- arguments += ',';
- }
- sig += a.normalizedType;
- arguments += a.name;
- }
- sig += ')';
-
- char flags = type;
- if (f.access == FunctionDef::Private)
- flags |= AccessPrivate;
- else if (f.access == FunctionDef::Public)
- flags |= AccessPublic;
- else if (f.access == FunctionDef::Protected)
- flags |= AccessProtected;
- if (f.access == FunctionDef::Private)
- flags |= AccessPrivate;
- else if (f.access == FunctionDef::Public)
- flags |= AccessPublic;
- else if (f.access == FunctionDef::Protected)
- flags |= AccessProtected;
- if (f.isCompat)
- flags |= MethodCompatibility;
- if (f.wasCloned)
- flags |= MethodCloned;
- if (f.isScriptable)
- flags |= MethodScriptable;
-
- meta_data << strreg(sig)
- << strreg(arguments)
- << strreg(f.normalizedType)
- << strreg(f.tag)
- << flags;
- }
-}
-
-void Generator::_generateEnums(int index)
-{
- index += 4 * cdef->enumList.count();
- int i;
- for (i = 0; i < cdef->enumList.count(); ++i) {
- const EnumDef &e = cdef->enumList.at(i);
- meta_data << strreg(e.name) << (cdef->enumDeclarations.value(e.name) ? 1 : 0)
- << e.values.count() << index;
- index += e.values.count() * 2;
- }
-
- for (i = 0; i < cdef->enumList.count(); ++i) {
- const EnumDef &e = cdef->enumList.at(i);
- for (int j = 0; j < e.values.count(); ++j) {
- const QByteArray &val = e.values.at(j);
- meta_data << strreg(val) << 0; // we don't know the value itself
- }
- }
-}
-
-void Generator::_generateProperties()
-{
- //
- // specify get function, for compatibiliy we accept functions
- // returning pointers, or const char * for QByteArray.
- //
- for (int i = 0; i < cdef->propertyList.count(); ++i) {
- PropertyDef &p = cdef->propertyList[i];
- if (p.read.isEmpty())
- continue;
- for (int j = 0; j < cdef->publicList.count(); ++j) {
- const FunctionDef &f = cdef->publicList.at(j);
- if (f.name != p.read)
- continue;
- if (!f.isConst) // get functions must be const
- continue;
- if (f.arguments.size()) // and must not take any arguments
- continue;
- PropertyDef::Specification spec = PropertyDef::ValueSpec;
- QByteArray tmp = f.normalizedType;
- if (p.type == "QByteArray" && tmp == "const char *")
- tmp = "QByteArray";
- if (tmp.left(6) == "const ")
- tmp = tmp.mid(6);
- if (p.type != tmp && tmp.endsWith('*')) {
- tmp.chop(1);
- spec = PropertyDef::PointerSpec;
- } else if (f.type.name.endsWith('&')) { // raw type, not normalized type
- spec = PropertyDef::ReferenceSpec;
- }
- if (p.type != tmp)
- continue;
- p.gspec = spec;
- break;
- }
- }
-
-
- //
- // Create meta data
- //
-
- for (int i = 0; i < cdef->propertyList.count(); ++i) {
- const PropertyDef &p = cdef->propertyList.at(i);
- uint flags = Invalid;
- if (!isVariantType(p.type)) {
- flags |= EnumOrFlag;
- } else {
- flags |= qvariant_nameToType(p.type) << 24;
- }
- if (!p.read.isEmpty())
- flags |= Readable;
- if (!p.write.isEmpty()) {
- flags |= Writable;
- if (p.stdCppSet())
- flags |= StdCppSet;
- }
- if (!p.reset.isEmpty())
- flags |= Resettable;
-
-// if (p.override)
-// flags |= Override;
-
- if (p.designable.isEmpty())
- flags |= ResolveDesignable;
- else if (p.designable != "false")
- flags |= Designable;
-
- if (p.scriptable.isEmpty())
- flags |= ResolveScriptable;
- else if (p.scriptable != "false")
- flags |= Scriptable;
-
- if (p.stored.isEmpty())
- flags |= ResolveStored;
- else if (p.stored != "false")
- flags |= Stored;
-
- if (p.editable.isEmpty())
- flags |= ResolveEditable;
- else if (p.editable != "false")
- flags |= Editable;
-
- if (p.user.isEmpty())
- flags |= ResolveUser;
- else if (p.user != "false")
- flags |= User;
-
- meta_data << strreg(p.name) << strreg(p.type) << flags;
- }
-}
-
QT_END_NAMESPACE