Alien-SmokeQt

 view release on metacpan or  search on metacpan

generator/generators/smoke/writeSmokeDataFile.cpp  view on Meta::CPAN

        }
    }
    
    // build class index here because the list needs to be sorted
    int i = 1;
    for (QMap<QString, int>::iterator iter = classIndex.begin(); iter != classIndex.end(); iter++) {
        iter.value() = i++;
    }
}

bool SmokeDataFile::isClassUsed(const Class* klass)
{
    for (QSet<Type*>::const_iterator it = usedTypes.constBegin(); it != usedTypes.constEnd(); it++) {
        if ((*it)->getClass() == klass)
            return true;
    }
    return false;
}

QString SmokeDataFile::getTypeFlags(const Type *t, int *classIdx)
{
    if (t->getTypedef()) {
        Type resolved = t->getTypedef()->resolve();
        return getTypeFlags(&resolved, classIdx);
    }

    QString flags = "0";
    if (Options::voidpTypes.contains(t->name())) {
        // support some of the weird quirks the kalyptus code has
        flags += "|Smoke::t_voidp";
    } else if (t->getClass()) {
        if (t->getClass()->isTemplate()) {
            if (Options::qtMode && t->getClass()->name() == "QFlags" && !t->isRef() && t->pointerDepth() == 0) {
                flags += "|Smoke::t_uint";
            } else {
                flags += "|Smoke::t_voidp";
            }
        } else {
            flags += "|Smoke::t_class";
            *classIdx = classIndex.value(t->getClass()->toString(), 0);
        }
    } else if (t->isIntegral() && t->name() != "void" && t->pointerDepth() == 0 && !t->isRef()) {
        flags += "|Smoke::t_";
        QString typeName = t->name();

        // replace the unsigned stuff, look the type up in Util::typeMap and if
        // necessary, add a 'u' for unsigned types at the beginning again
        bool _unsigned = false;
        if (typeName.startsWith("unsigned ")) {
            typeName.replace("unsigned ", "");
            _unsigned = true;
        }
        typeName.replace("signed ", "");
        typeName = Util::typeMap.value(typeName, typeName);
        if (_unsigned)
            typeName.prepend('u');

        flags += typeName;
    } else if (t->getEnum()) {
        flags += "|Smoke::t_enum";
        if (t->getEnum()->parent()) {
            *classIdx = classIndex.value(t->getEnum()->parent()->toString(), 0);
        } else if (!t->getEnum()->nameSpace().isEmpty()) {
            *classIdx = classIndex.value(t->getEnum()->nameSpace(), 0);
        } else {
            *classIdx = classIndex.value("QGlobalSpace", 0);
        }
    } else {
        flags += "|Smoke::t_voidp";
    }

    if (t->isRef())
        flags += "|Smoke::tf_ref";
    if (t->pointerDepth() > 0)
        flags += "|Smoke::tf_ptr";
    if (!t->isRef() && t->pointerDepth() == 0)
        flags += "|Smoke::tf_stack";
    if (t->isConst())
        flags += "|Smoke::tf_const";
    flags.replace("0|", "");

    return flags;
}

void SmokeDataFile::write()
{
    qDebug("writing out smokedata.cpp [%s]", qPrintable(Options::module));
    QFile smokedata(Options::outputDir.filePath("smokedata.cpp"));
    smokedata.open(QFile::ReadWrite | QFile::Truncate);
    QTextStream out(&smokedata);
    foreach (const QFileInfo& file, Options::headerList)
        out << "#include <" << file.fileName() << ">\n";
    out << "\n#include <smoke.h>\n";
    out << "#include <" << Options::module << "_smoke.h>\n\n";
    
    QString smokeNamespaceName = "__smoke" + Options::module;
    
    out << "namespace " << smokeNamespaceName  << " {\n\n";
    
    // write out Options::module_cast() function
    out << "static void *cast(void *xptr, Smoke::Index from, Smoke::Index to) {\n";
    out << "  switch(from) {\n";
    for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
        const Class& klass = classes[iter.key()];
        if (klass.isNameSpace())
            continue;
        
        QSet<int> indices; // avoid duplicate case values (diamond-shaped inheritance)
        
        out << "    case " << iter.value() << ":   //" << iter.key() << "\n";
        out << "      switch(to) {\n";
        foreach (const Class* base, Util::superClassList(&klass)) {
            QString className = base->toString();
            
            if (includedClasses.contains(className) || externalClasses.contains((Class *) base)) {
                int index = classIndex[className];
                if (indices.contains(index))
                    continue;
                indices << index;
                
                out << QString("        case %1: return (void*)(%2*)(%3*)xptr;\n")
                    .arg(index).arg(className).arg(klass.toString());

generator/generators/smoke/writeSmokeDataFile.cpp  view on Meta::CPAN

        out << "      }\n";
    }
    out << "    default: return xptr;\n";
    out << "  }\n";
    out << "}\n\n";
    
    // write out the inheritance list
    QHash<QVector<int>, int> inheritanceList;
    QHash<const Class*, int> inheritanceIndex;
    out << "// Group of Indexes (0 separated) used as super class lists.\n";
    out << "// Classes with super classes have an index into this array.\n";
    out << "static Smoke::Index inheritanceList[] = {\n";
    out << "    0,\t// 0: (no super class)\n";
    
    int currentIdx = 1;
    for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
        Class& klass = classes[iter.key()];
        if (!klass.baseClasses().count() || externalClasses.contains(&klass))
            continue;
        QVector<int> indices;
        QStringList comment;
        foreach (const Class::BaseClassSpecifier& base, klass.baseClasses()) {
            if (base.access == Access_private)
                continue;
            QString className = base.baseClass->toString();
            indices << classIndex[className];
            comment << className;
        }
        if (indices.count() == 0)
            continue;
        int idx = 0;
        
        if (!inheritanceList.contains(indices)) {
            idx = currentIdx;
            inheritanceList[indices] = idx;
            out << "    ";
            for (int i = 0; i < indices.count(); i++) {
                if (i > 0) out << ", ";
                out << indices[i];
                currentIdx++;
            }
            currentIdx++;
            out << ", 0,\t// " << idx << ": " << comment.join(", ") << "\n";
        } else {
            idx = inheritanceList[indices];
        }
        
        // store the index into inheritanceList for the class
        inheritanceIndex[&klass] = idx;
    }
    out << "};\n\n";
    
    // xenum functions
    out << "// These are the xenum functions for manipulating enum pointers\n";
    QSet<QString> enumClassesHandled;
    for (QHash<QString, Enum>::const_iterator it = enums.constBegin(); it != enums.constEnd(); it++) {
        if (!it.value().isValid())
            continue;
        
        QString smokeClassName;
        if (it.value().parent()) {
            smokeClassName = it.value().parent()->toString();
        } else {
            smokeClassName = it.value().nameSpace();
        }
        
        if (!smokeClassName.isEmpty() && includedClasses.contains(smokeClassName) && it.value().access() != Access_private) {
            if (enumClassesHandled.contains(smokeClassName) || Options::voidpTypes.contains(smokeClassName))
                continue;
            enumClassesHandled << smokeClassName;
            smokeClassName.replace("::", "__");
            out << "void xenum_" << smokeClassName << "(Smoke::EnumOperation, Smoke::Index, void*&, long&);\n";
        } else if (smokeClassName.isEmpty() && it.value().access() != Access_private) {
            if (enumClassesHandled.contains("QGlobalSpace"))
                continue;
            out << "void xenum_QGlobalSpace(Smoke::EnumOperation, Smoke::Index, void*&, long&);\n";
            enumClassesHandled << "QGlobalSpace";
        }
    }
    
    // xcall functions
    out << "\n// Those are the xcall functions defined in each x_*.cpp file, for dispatching method calls\n";
    for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
        Class& klass = classes[iter.key()];
        if (externalClasses.contains(&klass) || klass.isTemplate())
            continue;
        QString smokeClassName = QString(klass.toString()).replace("::", "__");
        out << "void xcall_" << smokeClassName << "(Smoke::Index, void*, Smoke::Stack);\n";
    }
    
    // classes table
    out << "\n// List of all classes\n";
    out << "// Name, external, index into inheritanceList, method dispatcher, enum dispatcher, class flags, size\n";
    out << "static Smoke::Class classes[] = {\n";
    out << "    { 0L, false, 0, 0, 0, 0, 0 },\t// 0 (no class)\n";
    int classCount = 0;
    for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
        if (!iter.value())
            continue;
        
        Class* klass = &classes[iter.key()];
        
        if (externalClasses.contains(klass)) {
            out << "    { \""  << iter.key() << "\", true, 0, 0, 0, 0, 0 },\t//" << iter.value() << "\n";
        } else {
            QString smokeClassName = QString(iter.key()).replace("::", "__");
            out << "    { \"" << iter.key() << "\", false" << ", "
                << inheritanceIndex.value(klass, 0) << ", xcall_" << smokeClassName << ", "
                << (enumClassesHandled.contains(iter.key()) ? QString("xenum_").append(smokeClassName) : "0") << ", ";
            QString flags = "0";
            if (!klass->isNameSpace()) {
                if (Util::canClassBeInstanciated(klass)) flags += "|Smoke::cf_constructor";
                if (Util::canClassBeCopied(klass)) flags += "|Smoke::cf_deepcopy";
                if (Util::hasClassVirtualDestructor(klass)) flags += "|Smoke::cf_virtual";
                flags.replace("0|", ""); // beautify
            } else {
                flags = "Smoke::cf_namespace";
            }
            out << flags << ", ";
            if (!klass->isNameSpace())
                out << "sizeof(" << iter.key() << ")";
            else

generator/generators/smoke/writeSmokeDataFile.cpp  view on Meta::CPAN

                
                // comment
                out << "  // " << klass->toString() << "::" << member->name();
                const Method* meth = 0;
                if ((meth = dynamic_cast<const Method*>(member))) {
                    out << '(';
                    for (int j = 0; j < meth->parameters().count(); j++) {
                        if (j > 0) out << ", ";
                        out << meth->parameters()[j].type()->toString();
                    }
                    out << ')';
                    if (meth->isConst()) out << " const";
                }
                out << "\n";
            }
            out << "    0,\n";
            ambigiousIds[klass][munged_it.key()] = i;
            i += munged_it.value().size() + 1;
        }
    }

    out << "};\n\n";

    int methodMapCount = 1;
    out << "// Class ID, munged name ID (index into methodNames), method def (see methods) if >0 or number of overloads if <0\n";
    out << "static Smoke::MethodMap methodMaps[] = {\n";
    out << "    {0, 0, 0},\t//0 (no method)\n";

    for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
        Class* klass = &classes[iter.key()];
        if (externalClasses.contains(klass))
            continue;
        
        QMap<QString, QList<const Member*> >& map = classMungedNames[klass];
        for (QMap<QString, QList<const Member*> >::const_iterator munged_it = map.constBegin(); munged_it != map.constEnd(); munged_it++) {
            
            // class index, munged name index
            out << "    {" << classIndex[iter.key()] << ", " << methodNames[munged_it.key()] << ", ";
            
            // if there's only one matching method for this class and the munged name, insert the index into methodss
            if (munged_it.value().size() == 1) {
                out << methodIdx[munged_it.value().first()];
            } else {
                // negative index into ambigious methods list
                out << '-' << ambigiousIds[klass][munged_it.key()];
            }
            out << "},";
            // comment
            out << "\t// " << klass->toString() << "::" << munged_it.key();
            out << "\n";
            methodMapCount++;
        }
    }

    out << "};\n\n";

    out << "}\n\n";

    out << "extern \"C\" {\n\n";

    for (int j = 0; j < Options::parentModules.count(); j++) {
        out << "SMOKE_IMPORT void init_" << Options::parentModules[j] << "_Smoke();\n";
        if (j == Options::parentModules.count() - 1)
            out << "\n";
    }

    out << "static bool initialized = false;\n";
    out << "Smoke *" << Options::module << "_Smoke = 0;\n\n";
    out << "// Create the Smoke instance encapsulating all the above.\n";
    out << "void init_" << Options::module << "_Smoke() {\n";
    foreach (const QString& str, Options::parentModules) {
        out << "    init_" << str << "_Smoke();\n";
    }
    out << "    if (initialized) return;\n";
    out << "    " << Options::module << "_Smoke = new Smoke(\n";
    out << "        \"" << Options::module << "\",\n";
    out << "        " << smokeNamespaceName << "::classes, " << classCount << ",\n";
    out << "        " << smokeNamespaceName << "::methods, " << methodCount << ",\n";
    out << "        " << smokeNamespaceName << "::methodMaps, " << methodMapCount << ",\n";
    out << "        " << smokeNamespaceName << "::methodNames, " << methodNames.count() << ",\n";
    out << "        " << smokeNamespaceName << "::types, " << typeIndex.count() << ",\n";
    out << "        " << smokeNamespaceName << "::inheritanceList,\n";
    out << "        " << smokeNamespaceName << "::argumentList,\n";
    out << "        " << smokeNamespaceName << "::ambiguousMethodList,\n";
    out << "        " << smokeNamespaceName << "::cast );\n";
    out << "    initialized = true;\n";
    out << "}\n\n";
    out << "void delete_" << Options::module << "_Smoke() { delete " << Options::module << "_Smoke; }\n\n";
    out << "}\n";

    smokedata.close();
}



( run in 2.705 seconds using v1.01-cache-2.11-cpan-140bd7fdf52 )