Ejemplo n.º 1
0
int runMoc(int _argc, char **_argv)
{
    bool autoInclude = true;
    Preprocessor pp;
    Moc moc;
    pp.macros["Q_MOC_RUN"];
    pp.macros["__cplusplus"];
    QByteArray filename;
    QByteArray output;
    FILE *in = 0;
    FILE *out = 0;
    bool ignoreConflictingOptions = false;

    QVector<QByteArray> argv;
    argv.resize(_argc - 1);
    for (int n = 1; n < _argc; ++n)
        argv[n - 1] = _argv[n];
    int argc = argv.count();

    for (int n = 0; n < argv.count(); ++n) {
        if (argv.at(n).startsWith('@')) {
            QByteArray optionsFile = argv.at(n);
            optionsFile.remove(0, 1);
            if (optionsFile.isEmpty())
                error("The @ option requires an input file");
            QFile f(QString::fromLatin1(optionsFile.constData()));
            if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
                error("Cannot open options file specified with @");
            argv.remove(n);
            while (!f.atEnd()) {
                QByteArray line = f.readLine().trimmed();
                if (!line.isEmpty())
                    argv.insert(n++, line);
            }
        }
    }

    argc = argv.count();

    for (int n = 0; n < argc; ++n) {
        QByteArray arg(argv[n]);
        if (arg[0] != '-') {
            if (filename.isEmpty()) {
                filename = arg;
                continue;
            }
            error("Too many input files specified");
        }
        QByteArray opt = arg.mid(1);
        bool more = (opt.size() > 1);
        switch (opt[0]) {
        case 'o': // output redirection
            if (!more) {
                if (!(n < argc-1))
                    error("Missing output file name");
                output = argv[++n];
            } else
                output = opt.mid(1);
            break;
        case 'E': // only preprocessor
            pp.preprocessOnly = true;
            break;
        case 'i': // no #include statement
            if (more)
                error();
            moc.noInclude        = true;
            autoInclude = false;
            break;
        case 'f': // produce #include statement
            if (ignoreConflictingOptions)
                break;
            moc.noInclude        = false;
            autoInclude = false;
            if (opt[1])                        // -fsomething.h
                moc.includeFiles.append(opt.mid(1));
            break;
        case 'p': // include file path
            if (ignoreConflictingOptions)
                break;
            if (!more) {
                if (!(n < argc-1))
                    error("Missing path name for the -p option.");
                moc.includePath = argv[++n];
            } else {
                moc.includePath = opt.mid(1);
            }
            break;
        case 'I': // produce #include statement
            if (!more) {
                if (!(n < argc-1))
                    error("Missing path name for the -I option.");
                pp.includes += Preprocessor::IncludePath(argv[++n]);
            } else {
                pp.includes += Preprocessor::IncludePath(opt.mid(1));
            }
            break;
        case 'F': // minimalistic framework support for the mac
            if (!more) {
                if (!(n < argc-1))
                    error("Missing path name for the -F option.");
                Preprocessor::IncludePath p(argv[++n]);
                p.isFrameworkPath = true;
                pp.includes += p;
            } else {
                Preprocessor::IncludePath p(opt.mid(1));
                p.isFrameworkPath = true;
                pp.includes += p;
            }
            break;
        case 'D': // define macro
            {
                QByteArray name;
                QByteArray value("1");
                if (!more) {
                    if (n < argc-1)
                        name = argv[++n];
                } else
                    name = opt.mid(1);
                int eq = name.indexOf('=');
                if (eq >= 0) {
                    value = name.mid(eq + 1);
                    name = name.left(eq);
                }
                if (name.isEmpty())
                    error("Missing macro name");
                Macro macro;
                macro.symbols += Symbol(0, PP_IDENTIFIER, value);
                pp.macros.insert(name, macro);

            }
            break;
        case 'U':
            {
                QByteArray macro;
                if (!more) {
                    if (n < argc-1)
                        macro = argv[++n];
                } else
                    macro = opt.mid(1);
                if (macro.isEmpty())
                    error("Missing macro name");
                pp.macros.remove(macro);

            }
            break;
        case 'v':  // version number
            if (more && opt != "version")
                error();
            fprintf(stderr, "Qt Meta Object Compiler version %d (Qt %s)\n",
                    mocOutputRevision, QT_VERSION_STR);
            return 1;
        case 'n': // don't display warnings
            if (ignoreConflictingOptions)
                break;
            if (opt != "nw")
                error();
            moc.displayWarnings = false;
            break;
        case 'h': // help
            if (more && opt != "help")
                error();
            else
                error(0); // 0 means usage only
            break;
        case '-':
            if (more && arg == "--ignore-option-clashes") {
                // -- ignore all following moc specific options that conflict
                // with for example gcc, like -pthread conflicting with moc's
                // -p option.
                ignoreConflictingOptions = true;
                break;
            }
            // fall through
        default:
            error();
        }
    }


    if (autoInclude) {
        int ppos = filename.lastIndexOf('.');
        moc.noInclude = (ppos >= 0
                         && tolower(filename[ppos + 1]) != 'h'
                         && tolower(filename[ppos + 1]) != QDir::separator().toLatin1()
                        );
    }
    if (moc.includeFiles.isEmpty()) {
        if (moc.includePath.isEmpty()) {
            if (filename.size()) {
                if (output.size())
                    moc.includeFiles.append(combinePath(filename, output));
                else
                    moc.includeFiles.append(filename);
            }
        } else {
            moc.includeFiles.append(combinePath(filename, filename));
        }
    }

    if (filename.isEmpty()) {
        filename = "standard input";
        in = stdin;
    } else {
#if defined(_MSC_VER) && _MSC_VER >= 1400
		if (fopen_s(&in, filename.data(), "rb")) {
#else
        in = fopen(filename.data(), "rb");
		if (!in) {
#endif
            fprintf(stderr, "moc: %s: No such file\n", (const char*)filename);
            return 1;
        }
        moc.filename = filename;
    }

    moc.currentFilenames.push(filename);

    // 1. preprocess
    moc.symbols = pp.preprocessed(moc.filename, in);
    fclose(in);

    if (!pp.preprocessOnly) {
        // 2. parse
        moc.parse();
    }

    // 3. and output meta object code

    if (output.size()) { // output file specified
#if defined(_MSC_VER) && _MSC_VER >= 1400
        if (fopen_s(&out, output.data(), "w"))
#else
        out = fopen(output.data(), "w"); // create output file
        if (!out)
#endif
        {
            fprintf(stderr, "moc: Cannot create %s\n", (const char*)output);
            return 1;
        }
    } else { // use stdout
        out = stdout;
    }

    if (pp.preprocessOnly) {
        fprintf(out, "%s\n", composePreprocessorOutput(moc.symbols).constData());
    } else {
        if (moc.classList.isEmpty())
            moc.warning("No relevant classes found. No output generated.");
        else
            moc.generate(out);
    }

    if (output.size())
        fclose(out);

    return 0;
}

QT_END_NAMESPACE

int main(int _argc, char **_argv)
{
    return QT_PREPEND_NAMESPACE(runMoc)(_argc, _argv);
}
Ejemplo n.º 2
0
static int mocreader_parse(lua_State *L)
{
	Preprocessor pp = initPreprocessor();
	Moc moc;
	
	QByteArray filename = luaL_checkstring(L, 1);
    QByteArray output;
	FILE *in = 0;
    FILE *out = 0;

	//TODO: read options:
	// no warning
	// no noting
	if (lua_istable(L, 2)){
		readPreprocessorParams(L, 2, pp);
	}

	in = fopen(filename.data(), "rb");
	if (!in) {
        luaL_error(L, "moc: %s: No such file\n", filename.constData());
    }

	moc.currentFilenames.push(filename);
	moc.symbols = pp.preprocessed(moc.filename, in);
    fclose(in);
	
	moc.parse();

	lua_createtable(L, moc.classList.size(), 0);
	for (size_t i = 0; i < moc.classList.size(); ++i)
	{
		const ClassDef& def = moc.classList[i];
		lua_createtable(L, 0, 20);

		// classname
		lua_pushstring(L, def.classname.data());
		lua_setfield(L, -2, "classname");

		// qualified
		lua_pushstring(L, def.qualified.data());
		lua_setfield(L, -2, "qualified");

		// superclasses
		lua_createtable(L, def.superclassList.size(), 0);
		for (size_t j = 0; j < def.superclassList.size(); ++j)
		{
			lua_createtable(L, 0, 2);
			
			lua_pushstring(L, def.superclassList[j].first);
			lua_setfield(L, -2, "name");

			lua_pushFunctionDef_Access(L, def.superclassList[j].second);
			lua_setfield(L, -2, "access");

			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "superclassList");

		// interfaces
		// Don't know why interface list is a 2-dimensions list?
		lua_createtable(L, def.interfaceList.size(), 0);
		for (size_t j = 0; j < def.interfaceList.size(); ++j)
		{
			const QList<ClassDef::Interface>& list = def.interfaceList[j];
			lua_createtable(L, list.size(), 0);
			for (size_t k = 0; k < list.size(); ++k){
				lua_createtable(L, 0, 2);
				
				lua_pushstring(L, list[k].className);
				lua_setfield(L, -2, "className");

				lua_pushstring(L, list[k].interfaceId);
				lua_setfield(L, -2, "interfaceId");

				lua_rawseti(L, -2, k+1);
			}
			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "interfaceList");

		// Don't know what does hasQObject&hasQGadget means, skipping.

		// pluginData
		lua_createtable(L, 0, 2);
		{
			lua_pushstring(L, def.pluginData.iid);
			lua_setfield(L, -2, "iid");

			lua_pushstring(L, def.pluginData.metaData.toJson());
			lua_setfield(L, -2, "metaData");
		}
		lua_setfield(L, -2, "pluginData");
		
		// constructorList
		lua_createtable(L, def.constructorList.size(), 0);
		for (size_t j = 0; j < def.constructorList.size(); ++j)
		{
			lua_pushFunctionDef(L, def.constructorList[j]);
			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "constructorList");

		// signalList
		lua_createtable(L, def.signalList.size(), 0);
		for (size_t j = 0; j < def.signalList.size(); ++j)
		{
			lua_pushFunctionDef(L, def.signalList[j]);
			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "signalList");

		// slotList
		lua_createtable(L, def.slotList.size(), 0);
		for (size_t j = 0; j < def.slotList.size(); ++j)
		{
			lua_pushFunctionDef(L, def.slotList[j]);
			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "slotList");

		// methodList
		lua_createtable(L, def.methodList.size(), 0);
		for (size_t j = 0; j < def.methodList.size(); ++j)
		{
			lua_pushFunctionDef(L, def.methodList[j]);
			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "methodList");

		// publicList
		lua_createtable(L, def.publicList.size(), 0);
		for (size_t j = 0; j < def.publicList.size(); ++j)
		{
			lua_pushFunctionDef(L, def.publicList[j]);
			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "publicList");

		// notifyableProperties
		lua_pushinteger(L, def.notifyableProperties);
		lua_setfield(L, -2, "notifyableProperties");

		// propertyList
		lua_createtable(L, def.propertyList.size(), 0);
		for (size_t j = 0; j < def.propertyList.size(); ++j)
		{
			lua_pushPropertyDef(L, def.propertyList[j]);
			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "propertyList");

		// classInfoList
		lua_createtable(L, def.classInfoList.size(), 0);
		for (size_t j = 0; j < def.classInfoList.size(); ++j)
		{
			lua_pushClassInfoDef(L, def.classInfoList[j]);
			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "classInfoList");

		//enumDeclarations
		lua_createtable(L, 0, def.enumDeclarations.size());
		for (QMap<QByteArray, bool>::const_iterator itor = def.enumDeclarations.begin();
			itor != def.enumDeclarations.end();
			++itor)
		{
			lua_pushboolean(L, itor.value());
			lua_setfield(L, -2, itor.key());
		}
		lua_setfield(L, -2, "enumDeclarations");

		// enumList
		lua_createtable(L, def.enumList.size(), 0);
		for (size_t j = 0; j < def.enumList.size(); ++j)
		{
			lua_pushEnumDef(L, def.enumList[j]);
			lua_rawseti(L, -2, j+1);
		}
		lua_setfield(L, -2, "enumList");

		//flagAliases
		lua_createtable(L, 0, def.flagAliases.size());
		for (QMap<QByteArray, QByteArray>::const_iterator itor = def.flagAliases.begin();
			itor != def.flagAliases.end();
			++itor)
		{
			lua_pushstring(L, itor.value());
			lua_setfield(L, -2, itor.key());
		}
		lua_setfield(L, -2, "flagAliases");

		lua_pushinteger(L, def.revisionedMethods);
		lua_setfield(L, -2, "revisionedMethods");

		lua_pushinteger(L, def.revisionedProperties);
		lua_setfield(L, -2, "revisionedProperties");

		lua_pushinteger(L, def.begin);
		lua_setfield(L, -2, "begin");

		lua_pushinteger(L, def.end);
		lua_setfield(L, -2, "end");

		lua_rawseti(L, -2, i+1);
	}
	
	return 1;
}