예제 #1
0
void Project::readPlatformSettings( const QString &contents,
				    const QString &setting,
				    QMap<QString, QString> &res )
{
    const QString platforms[] = { "", "win32", "unix", "mac", "os2", QString::null };
    for ( int i = 0; platforms[ i ] != QString::null; ++i ) {
	QString p = platforms[ i ];
	if ( !p.isEmpty() )
	    p += ":";
	QStringList lst = parse_multiline_part( contents, p + setting );
	QString s = lst.join( " " );
	QString key = platforms[ i ];
	if ( key.isEmpty() )
	    key = "(all)";
	res.replace( key, s );
    }
}
예제 #2
0
void Project::save( bool onlyProjectFile )
{
    bool anythingModified = FALSE;

    //  save sources and forms
    if ( !onlyProjectFile ) {

	saveConnections();

	for ( SourceFile *sf = sourcefiles.first(); sf; sf = sourcefiles.next() ) {
	    anythingModified = anythingModified || sf->isModified();
	    if ( !sf->save() )
		return;
	}

	for ( FormFile *ff = formfiles.first(); ff; ff = formfiles.next() ) {
	    anythingModified = anythingModified || ff->isModified();
	    if ( !ff->save() )
		return;
	}
    }

    if ( isDummy() || filename.isEmpty() )
	return;

    if ( !modified ) {
	if ( singleProjectMode() ) {
	    LanguageInterface *iface = MetaDataBase::languageInterface( language() );
	    if ( iface && iface->supports( LanguageInterface::CompressProject ) )
		iface->compressProject( makeAbsolute( filename ), singleProFileName, anythingModified );
	}
 	return;
    }

    QFile f( filename );
    QString original = "";

    // read the existing file
    bool hasPreviousContents = FALSE;
    if ( f.open( IO_ReadOnly ) ) {
	QTextStream ts( &f );
	original = ts.read();
	f.close();
        hasPreviousContents = TRUE;
	remove_contents( original, "{SOURCES+=" ); // ### compatibility with early 3.0 betas
	remove_contents( original, "DBFILE" );
	remove_contents( original, "LANGUAGE" );
	remove_contents( original, "TEMPLATE" );
	removePlatformSettings( original, "CONFIG" );
	removePlatformSettings( original, "DEFINES" );
	removePlatformSettings( original, "LIBS" );
	removePlatformSettings( original, "INCLUDEPATH" );
	removePlatformSettings( original, "SOURCES" );
	removePlatformSettings( original, "HEADERS" );
	remove_multiline_contents( original, "FORMS" );
	remove_multiline_contents( original, "INTERFACES" ); // compatibility
	remove_multiline_contents( original, "IMAGES" );
	for ( QStringList::Iterator it = csList.begin(); it != csList.end(); ++it )
	    remove_contents( original, *it );
    }

    if (!original.isEmpty()) {
	// Removes any new lines at the beginning of the file
	while (original.startsWith("\n"))
	    original.remove(0, 1);
    }

    // the contents of the saved file
    QString contents;

    // template
    contents += "TEMPLATE\t= " + templ + "\n";

    // language
    contents += "LANGUAGE\t= " + lang + "\n";
    contents += "\n";

    // config
    writePlatformSettings( contents, "CONFIG", cfg );
    LanguageInterface *iface = MetaDataBase::languageInterface( lang );
    if ( iface ) {
	QStringList sourceKeys;
	iface->sourceProjectKeys( sourceKeys );
	for ( QStringList::Iterator spit = sourceKeys.begin(); spit != sourceKeys.end(); ++spit )
	    remove_multiline_contents( contents, *spit );
    }

    // libs, defines, includes
    writePlatformSettings( contents, "LIBS", lbs );
    writePlatformSettings( contents, "DEFINES", defs );
    writePlatformSettings( contents, "INCLUDEPATH", inclPath );
    writePlatformSettings( contents, "SOURCES", sources );
    writePlatformSettings( contents, "HEADERS", headers );

    // unix
    if ( !hasPreviousContents ) {
 	contents +=
 	    "unix|os2 {\n"
 	    "  UI_DIR = .ui\n"
 	    "  MOC_DIR = .moc\n"
 	    "  OBJECTS_DIR = .obj\n"
 	    "}\n\n";
    }

    // sources
    if ( !sourcefiles.isEmpty() && iface ) {
	QMap<QString, QStringList> sourceToKey;
	for ( SourceFile *f = sourcefiles.first(); f; f = sourcefiles.next() ) {
	    QString key = iface->projectKeyForExtension( QFileInfo( f->fileName() ).extension() );
	    QStringList lst = sourceToKey[ key ];
	    lst << makeRelative( f->fileName() );
	    sourceToKey.replace( key, lst );
	}

	for ( QMap<QString, QStringList>::Iterator skit = sourceToKey.begin();
	      skit != sourceToKey.end(); ++skit ) {
	    QString part = skit.key() + "\t+= ";
	    QStringList lst = *skit;
	    for ( QStringList::Iterator sit = lst.begin(); sit != lst.end(); ++sit ) {
		part += *sit;
		part += ++sit != lst.end() ? " \\\n\t" : "";
		--sit;
	    }
	    part += "\n\n";
	    contents += part;
	}
    }

    // forms and interfaces
    if ( !formfiles.isEmpty() ) {
	contents += "FORMS\t= ";
	for ( QPtrListIterator<FormFile> fit = formfiles; fit.current(); ++fit ) {
	    contents += fit.current()->fileName() +
		 (fit != formfiles.last() ? " \\\n\t" : "");
	}
	contents += "\n\n";
    }

    // images
     if ( !pixCollection->isEmpty() ) {
	contents += "IMAGES\t= ";
	QValueList<PixmapCollection::Pixmap> pixmaps = pixCollection->pixmaps();
	for ( QValueList<PixmapCollection::Pixmap>::Iterator it = pixmaps.begin();
	      it != pixmaps.end(); ++it ) {
		  contents += makeRelative( (*it).absname );
		  contents += ++it != pixmaps.end() ? " \\\n\t" : "";
		  --it;
	}
	contents += "\n\n";
    }

    // database
    if ( !dbFile.isEmpty() )
	contents += "DBFILE\t= " + dbFile + "\n";

    // custom settings
    for ( QStringList::Iterator it = csList.begin(); it != csList.end(); ++it ) {
	QString val = *customSettings.find( *it );
	if ( !val.isEmpty() )
	    contents += *it + "\t= " + val + "\n";
    }

    if ( !f.open( IO_WriteOnly | IO_Translate ) ) {
	QMessageBox::warning( messageBoxParent(),
			      "Save Project Failed", "Couldn't write project file " + filename );
	return;
    }

    QTextStream os( &f );
    os << contents;
    if (hasPreviousContents)
        os << original;

    f.close();

    setModified( FALSE );

    if ( singleProjectMode() ) {
	LanguageInterface *iface = MetaDataBase::languageInterface( language() );
	if ( iface && iface->supports( LanguageInterface::CompressProject ) )
	    iface->compressProject( makeAbsolute( filename ), singleProFileName, TRUE );
    }
}
예제 #3
0
QMap<QString, QString> proFileTagMap( const QString& text )
{
    QString t = text;
    QMap<QString, QString> tagMap;
    bool stillProcess = true; // If include() has a $$tag then we need to reprocess
    
    while(stillProcess) {

	/* 
	    Strip any commments before we try to include.  We
	    still need to do it after we include to make sure the
	    included file does not have comments
	*/
	t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") );

	/*
	    Process include() commands.
	    $$PWD is a special case so we have to change it while 
	    we know where the included file is.
        */
	QRegExp callToInclude("include\\s*\\(\\s*([^()\\s]+)\\s*\\)");
	int i = 0;
	while ( (i = callToInclude.search(t, i)) != -1 ) {
	    bool doneWithVar = false;
	    QString fileName = callToInclude.cap(1);
	    QString after = fileName.replace("$$PWD", QDir::currentDirPath());
	    if (!tagMap.isEmpty() && after.contains("$$")) {
		QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" );
		int ii = 0;
		while ((ii = after.find(var, ii)) != -1) {
		    if (tagMap.contains(var.cap(1))) {
			after.replace(ii, var.cap(0).length(), tagMap[var.cap(1)]);
		    } else { // Couldn't find it
			doneWithVar = true;
			break;
		    }
		}
		
	    }
	    if (doneWithVar || !after.contains("$$")) {
		after = loadFile(after);
		QFileInfo fi(callToInclude.cap(1));
		after.replace("$$PWD", fi.dirPath());
		t.replace( i, callToInclude.matchedLength(), after );
	    }
	    i += after.length();
	}

	/*
	    Strip comments, merge lines ending with backslash, add
	    spaces around '=' and '+=', replace '\n' with ';', and
	    simplify white spaces.
	*/
	t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") );
	t.replace( QRegExp(QString("\\\\[^\n\\S]*\n")), QString(" ") );
	t.replace( "=", QString(" = ") );
	t.replace( "+ =", QString(" += ") );
	t.replace( "\n", QString(";") );
	t = t.simplifyWhiteSpace();
	
	/*
	    Populate tagMap with 'key = value' entries.
	*/
	QStringList lines = QStringList::split( QChar(';'), t );
	QStringList::Iterator line;
	for ( line = lines.begin(); line != lines.end(); ++line ) {
	    QStringList toks = QStringList::split( QChar(' '), *line );
	    
	    if ( toks.count() >= 3 && 
		(toks[1] == QString("=") || toks[1] == QString("+=")) ) {
		QString tag = toks.first();
		int k = tag.findRev( QChar(':') ); // as in 'unix:'
		if ( k != -1 )
		    tag = tag.mid( k + 1 );
		toks.remove( toks.begin() );
		
		QString action = toks.first();
		toks.remove( toks.begin() );
		
		if ( tagMap.contains(tag) ) {
		    if ( action == QString("=") )
			tagMap.replace( tag, toks.join(QChar(' ')) );
		    else
			tagMap[tag] += QChar( ' ' ) + toks.join( QChar(' ') );
		} else {
		    tagMap[tag] = toks.join( QChar(' ') );
		}
	    }
	}
	
	/*
	    Expand $$variables within the 'value' part of a 'key = value'
	    pair.
	*/
	QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" );
	QMap<QString, QString>::Iterator it;
	for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
	    int i = 0;
	    while ( (i = var.search((*it), i)) != -1 ) {
		int len = var.matchedLength();
		QString invocation = var.cap(1);
		QString after;
		
		if ( invocation == "system" ) {
		    // skip system(); it will be handled in the next pass
		    ++i;
		} else {
		    if ( tagMap.contains(invocation) )
			after = tagMap[invocation];
		    else if (invocation.lower() == "pwd")
			after = QDir::currentDirPath();
		    (*it).replace( i, len, after );
		    i += after.length();
		}
	    }
	}
    
	/*
	  Execute system() calls.
	*/
	QRegExp callToSystem( "\\$\\$system\\s*\\(([^()]*)\\)" );
	for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
	    int i = 0;
	    while ( (i = callToSystem.search((*it), i)) != -1 ) {
		/*
		  This code is stolen from qmake's project.cpp file.
		  Ideally we would use the same parser, so we wouldn't
		  have this code duplication.
		*/
		QString after;
		char buff[256];
		FILE *proc = QT_POPEN( callToSystem.cap(1).latin1(), "r" );
		while ( proc && !feof(proc) ) {
		    int read_in = (int)fread( buff, 1, 255, proc );
		    if ( !read_in )
			break;
		    for ( int i = 0; i < read_in; i++ ) {
			if ( buff[i] == '\n' || buff[i] == '\t' )
			    buff[i] = ' ';
		    }
		    buff[read_in] = '\0';
		    after += buff;
		}
		(*it).replace( i, callToSystem.matchedLength(), after );
		i += after.length();
	    }
	}
	stillProcess = callToInclude.search(t) != -1;
    }
    return tagMap;
}