111 files changed, 4259 insertions, 1883 deletions
diff --git a/qmake/Makefile b/qmake/Makefile index 90b0f07..01bb1a1 100644 --- a/qmake/Makefile +++ b/qmake/Makefile @@ -5,19 +5,19 @@ QMAKESPECSDIR=$(OPIEDIR)/mkspecs ######################################################################## CC = gcc CXX = g++ #qmake code OBJS=project.o main.o makefile.o unixmake2.o unixmake.o borland_bmake.o \ - msvc_nmake.o msvc_dsp.o msvc_vcproj.o option.o winmakefile.o \ + mingw_make.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o option.o winmakefile.o \ projectgenerator.o metrowerks_xml.o pbuilder_pbx.o msvc_objectmodel.o #qt code QOBJS=qstring.o qtextstream.o qiodevice.o qglobal.o qgdict.o qcstring.o \ qdatastream.o qgarray.o qbuffer.o qglist.o qptrcollection.o qfile.o \ - qfile_unix.o qregexp.o qgvector.o qgcache.o qbitarray.o qdir.o \ + qfile_unix.o qregexp.o qgvector.o qgcache.o qbitarray.o qdir.o quuid.o \ qfileinfo_unix.o qdir_unix.o qfileinfo.o qdatetime.o qstringlist.o qmap.o \ qconfig.o CFLAGS= \ -I. -Igenerators -Igenerators/unix -Igenerators/win32 -Igenerators/mac \ -I$(OPIEDIR)/qmake/include -I$(OPIEDIR)/qmake/include/qmake -I$(QMAKESPECSDIR)/default \ @@ -95,12 +95,15 @@ qgcache.o: $(OPIEDIR)/qmake/tools/qgcache.cpp qbitarray.o: $(OPIEDIR)/qmake/tools/qbitarray.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qbitarray.cpp qdir.o: $(OPIEDIR)/qmake/tools/qdir.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qdir.cpp +quuid.o: $(OPIEDIR)/qmake/tools/quuid.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/quuid.cpp + qfileinfo_unix.o: $(OPIEDIR)/qmake/tools/qfileinfo_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qfileinfo_unix.cpp qdir_unix.o: $(OPIEDIR)/qmake/tools/qdir_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qdir_unix.cpp @@ -140,12 +143,15 @@ unixmake.o: generators/unix/unixmake.cpp unixmake2.o: generators/unix/unixmake2.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/unix/unixmake2.cpp borland_bmake.o: generators/win32/borland_bmake.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/borland_bmake.cpp +mingw_make.o: generators/win32/mingw_make.cpp + $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/mingw_make.cpp + msvc_objectmodel.o: generators/win32/msvc_objectmodel.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_objectmodel.cpp msvc_vcproj.o: generators/win32/msvc_vcproj.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_vcproj.cpp diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index f490313..c12375d 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -56,14 +56,28 @@ // Well, Windows doesn't have this, so here's the macro #ifndef S_ISDIR #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif +static QString mkdir_p_asstring(const QString &dir) +{ + QString ret = "@$(CHK_DIR_EXISTS) \"" + dir + "\" "; + if(Option::target_mode == Option::TARG_WIN_MODE) + ret += "$(MKDIR)"; + else + ret += "|| $(MKDIR)"; + ret += " \"" + dir + "\""; + return ret; +} + static bool createDir(const QString& fullPath) { + if(QFile::exists(fullPath)) + return FALSE; + QDir dirTmp; bool ret = TRUE; QString pathComponent, tmpPath; QStringList hierarchy = QStringList::split(QString(Option::dir_sep), fullPath, TRUE); for(QStringList::Iterator it = hierarchy.begin(); it != hierarchy.end(); ++it) { pathComponent = *it + QDir::separator(); @@ -74,29 +88,29 @@ static bool createDir(const QString& fullPath) } } return ret; } -MakefileGenerator::MakefileGenerator(QMakeProject *p) : init_opath_already(FALSE), - init_already(FALSE), moc_aware(FALSE), +MakefileGenerator::MakefileGenerator(QMakeProject *p) : init_opath_already(FALSE), + init_already(FALSE), moc_aware(FALSE), no_io(FALSE), project(p) { } static char *gimme_buffer(off_t s) { static char *big_buffer = NULL; static int big_buffer_size = 0; if(!big_buffer || big_buffer_size < s) - big_buffer = (char *)realloc(big_buffer, s); + big_buffer = (char *)realloc(big_buffer, s); return big_buffer; } bool -MakefileGenerator::generateMocList(QString fn_target) +MakefileGenerator::generateMocList(const QString &fn_target) { if(!findMocDestination(fn_target).isEmpty()) return TRUE; QString fn_local = Option::fixPathToLocalOS(fileFixify(fn_target, QDir::currentDirPath(), Option::output_dir)); @@ -170,34 +184,36 @@ MakefileGenerator::generateMocList(QString fn_target) len=DIS_LEN; } if(SYMBOL_CHAR(*(big_buffer+x+len))) interesting = FALSE; if(interesting) { *(big_buffer+x+len) = '\0'; - debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(), line_count, big_buffer+x); + debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(), + line_count, big_buffer+x); int ext_pos = fn_target.findRev('.'); int ext_len = fn_target.length() - ext_pos; int dir_pos = fn_target.findRev(Option::dir_sep, ext_pos); QString mocFile; if(!project->isEmpty("MOC_DIR")) mocFile = project->first("MOC_DIR"); else if(dir_pos != -1) mocFile = fn_target.left(dir_pos+1); bool cpp_ext = FALSE; - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { + for(QStringList::Iterator cppit = Option::cpp_ext.begin(); + cppit != Option::cpp_ext.end(); ++cppit) { if((cpp_ext = (fn_target.right(ext_len) == (*cppit)))) break; } if(cpp_ext) { mocFile += fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::moc_ext; - findDependencies(fn_target).append(mocFile); project->variables()["_SRCMOC"].append(mocFile); } else if(project->variables()["HEADERS"].findIndex(fn_target) != -1) { - for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { + for(QStringList::Iterator hit = Option::h_ext.begin(); + hit != Option::h_ext.end(); ++hit) { if((fn_target.right(ext_len) == (*hit))) { mocFile += Option::moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::cpp_ext.first(); logicWarn(mocFile, "SOURCES"); project->variables()["_HDRMOC"].append(mocFile); break; @@ -222,19 +238,18 @@ MakefileGenerator::generateMocList(QString fn_target) #undef OBJ_LEN #undef DIS_LEN return TRUE; } bool -MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QString fn, bool recurse) +MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const QString &f, bool recurse) { - fn = fileFixify(fn); - QStringList &fndeps = findDependencies(fn); + QStringList &fndeps = findDependencies(f); if(!fndeps.isEmpty()) return TRUE; - + QString fn = fileFixify(f, QDir::currentDirPath(), Option::output_dir); fn = Option::fixPathToLocalOS(fn, FALSE); QString fix_env_fn = Option::fixPathToLocalOS(fn); int file = open(fix_env_fn.latin1(), O_RDONLY); if(file == -1) return FALSE; struct stat fst; @@ -285,14 +300,16 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri } if(*(big_buffer + x) == '#') { x++; while(x < total_size_read && //Skip spaces after hash (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) x++; - if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include ", 8)) { - for(x+=8; //skip spaces after keyword + if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) && + (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '\t' || + *(big_buffer + x + 7) == '<' || *(big_buffer + x + 7) == '"')) { + for(x+=7; //skip spaces after keyword x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t'); x++); char term = *(big_buffer + x); if(term == '"'); else if(term == '<') term = '>'; @@ -325,13 +342,13 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri *(big_buffer + x + msg_len) = term; //put it back } } } else if(ui_file) { // skip whitespaces while(x < total_size_read && - (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) + (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) x++; if(*(big_buffer + x) == '<') { x++; if(total_size_read >= x + 12 && !strncmp(big_buffer + x, "includehint", 11) && (*(big_buffer + x + 11) == ' ' || *(big_buffer + x + 11) == '>')) { for(x += 12; *(big_buffer + x) != '>'; x++); @@ -339,13 +356,13 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri for(x += 1 ; *(big_buffer + x + inc_len) != '<'; inc_len++); *(big_buffer + x + inc_len) = '\0'; inc = big_buffer + x; } else if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) && (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '>')) { for(x += 8; *(big_buffer + x) != '>'; x++) { - if(total_size_read >= x + 9 && *(big_buffer + x) == 'i' && + if(total_size_read >= x + 9 && *(big_buffer + x) == 'i' && !strncmp(big_buffer + x, "impldecl", 8)) { for(x += 8; *(big_buffer + x) != '='; x++); if(*(big_buffer + x) != '=') continue; for(x++; *(big_buffer+x) == '\t' || *(big_buffer+x) == ' '; x++); char quote = 0; @@ -366,13 +383,13 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri char saved = *(big_buffer + x + val_len); *(big_buffer + x + val_len) = '\0'; QString where = big_buffer + x; *(big_buffer + x + val_len) = saved; if(where == "in implementation") { QString cpp = fn.left(fn.length() - Option::ui_ext.length()) + - Option::cpp_ext.first(); + Option::cpp_ext.first(); outdeps = &findDependencies(cpp); } } } int inc_len = 0; for(x += 1 ; *(big_buffer + x + inc_len) != '<'; inc_len++); @@ -380,12 +397,13 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri inc = big_buffer + x; } } } if(!inc.isEmpty()) { + bool from_source_dir = TRUE; debug_msg(5, "%s:%d Found dependency to %s", fix_env_fn.latin1(), line_count, inc.latin1()); if(!project->isEmpty("SKIP_DEPENDS")) { bool found = FALSE; QStringList &nodeplist = project->values("SKIP_DEPENDS"); for(QStringList::Iterator it = nodeplist.begin(); @@ -401,34 +419,35 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri } QString fqn; if(project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH") && !stat(fix_env_fndir + inc, &fst) && !S_ISDIR(fst.st_mode)) { fqn = fndir + inc; + goto handle_fqn; } else { if((Option::target_mode == Option::TARG_MAC9_MODE && inc.find(':')) || (Option::target_mode == Option::TARG_WIN_MODE && inc[1] != ':') || ((Option::target_mode == Option::TARG_UNIX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || Option::target_mode == Option::TARG_MACX_MODE) && inc[0] != '/')) { for(MakefileDependDir *mdd = dirs.first(); mdd; mdd = dirs.next() ) { if(!stat(mdd->local_dir + QDir::separator() + inc, &fst) && !S_ISDIR(fst.st_mode)) { fqn = mdd->real_dir + QDir::separator() + inc; - break; + goto handle_fqn; } } } } - if(fqn.isEmpty()) { + if(fqn.isEmpty() && Option::mkfile::do_dep_heuristics) { //these are some hacky heuristics it will try to do on an include //however these can be turned off at runtime, I'm not sure how //reliable these will be, most likely when problems arise turn it off //and see if they go away.. - if(Option::mkfile::do_dep_heuristics && depHeuristics.contains(inc)) { + if(depHeuristics.contains(inc)) { fqn = depHeuristics[inc]; } else if(Option::mkfile::do_dep_heuristics) { //some heuristics.. //is it a file from a .ui? QString inc_file = inc.section(Option::dir_sep, -1); int extn = inc_file.findRev('.'); if(extn != -1 && @@ -444,17 +463,40 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri fqn = project->first("UI_HEADERS_DIR"); else fqn = (*it).section(Option::dir_sep, 0, -2); if(!fqn.isEmpty() && !fqn.endsWith(Option::dir_sep)) fqn += Option::dir_sep; fqn += inc_file; - break; + from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) + fqn = fileFixify(fqn, QDir::currentDirPath(), Option::output_dir); + goto handle_fqn; + } + } + } + if(project->isActiveConfig("lex_included")) { //is this the lex file? + QString rhs = Option::lex_mod + Option::cpp_ext.first(); + if(inc.endsWith(rhs)) { + QString lhs = inc.left(inc.length() - rhs.length()) + Option::lex_ext; + QStringList ll = project->variables()["LEXSOURCES"]; + for(QStringList::Iterator it = ll.begin(); it != ll.end(); ++it) { + QString s = (*it), d; + int slsh = s.findRev(Option::dir_sep); + if(slsh != -1) { + d = s.left(slsh + 1); + s = s.right(s.length() - slsh - 1); + } + if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) + d = project->first("QMAKE_ABSOLUTE_SOURCE_PATH"); + if(s == lhs) { + fqn = d + inc; + goto handle_fqn; + } } } } - if(fqn.isEmpty()) { //is it from a .y? + { //is it from a .y? QString rhs = Option::yacc_mod + Option::h_ext.first(); if(inc.endsWith(rhs)) { QString lhs = inc.left(inc.length() - rhs.length()) + Option::yacc_ext; QStringList yl = project->variables()["YACCSOURCES"]; for(QStringList::Iterator it = yl.begin(); it != yl.end(); ++it) { QString s = (*it), d; @@ -464,25 +506,54 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri s = s.right(s.length() - slsh - 1); } if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) d = project->first("QMAKE_ABSOLUTE_SOURCE_PATH"); if(s == lhs) { fqn = d + inc; - break; + goto handle_fqn; + } + } + } + } + if(mocAware() && //is it a moc file? + (inc.endsWith(Option::cpp_ext.first()) || inc.endsWith(Option::moc_ext))) { + QString mocs[] = { QString("_HDRMOC"), QString("_SRCMOC"), QString::null }; + for(int moc = 0; !mocs[moc].isNull(); moc++) { + QStringList &l = project->variables()[mocs[moc]]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QString file = Option::fixPathToTargetOS((*it)); + if(file.section(Option::dir_sep, -(inc.contains('/')+1)) == inc) { + fqn = (*it); + if(mocs[moc] == "_HDRMOC") { + //Since it is include, no need to link it in as well + project->variables()["_SRCMOC"].append((*it)); + l.remove(it); + } else if(!findMocSource(fqn).endsWith(fn)) { + /* Not really a very good test, but this will at least avoid + confusion if it really does happen (since tmake/qmake + previously didn't even allow this the test is mostly accurate) */ + warn_msg(WarnLogic, + "Found potential multiple MOC include %s (%s) in '%s'", + inc.latin1(), fqn.latin1(), fix_env_fn.latin1()); + } + from_source_dir = FALSE; //mocs go in the output_dir (so don't fix them) + goto handle_fqn; } } } } depHeuristics.insert(inc, fqn); } - if(!Option::mkfile::do_dep_heuristics || fqn.isEmpty()) //I give up - continue; } - - fqn = fileFixify(Option::fixPathToTargetOS(fqn, FALSE)); - debug_msg(4, "Resolved dependancy of %s to %s", inc.latin1(), fqn.latin1()); + handle_fqn: + if(fqn.isEmpty()) //I give up + continue; + fqn = Option::fixPathToTargetOS(fqn, FALSE); + if(from_source_dir) + fqn = fileFixify(fqn); + debug_msg(4, "Resolved dependency of %s to %s", inc.latin1(), fqn.latin1()); if(outdeps && outdeps->findIndex(fqn) == -1) outdeps->append(fqn); } //read past new line now.. for( ; x < total_size_read && (*(big_buffer + x) != '\n'); x++); line_count++; @@ -494,13 +565,13 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri QStringList &deplist = findDependencies((*fnit)); for(QStringList::Iterator it = deplist.begin(); it != deplist.end(); ++it) if(fndeps.findIndex((*it)) == -1) fndeps.append((*it)); } } - debug_msg(2, "Dependancies: %s -> %s", fn.latin1(), fndeps.join(" :: ").latin1()); + debug_msg(2, "Dependencies: %s -> %s", fn.latin1(), fndeps.join(" :: ").latin1()); return TRUE; } void MakefileGenerator::initOutPaths() { @@ -610,13 +681,17 @@ MakefileGenerator::init() if(!l.isEmpty()) l = fileFixify(l); } /* get deps and mocables */ QDict<void> cache_found_files; - QString cache_file(Option::output_dir + QDir::separator() + ".qmake.internal.cache"); + QString cache_file(".qmake.internal.cache"); + if(!project->isEmpty("QMAKE_INTERNAL_CACHE_FILE")) + cache_file = Option::fixPathToLocalOS(project->first("QMAKE_INTERNAL_CACHE_FILE")); + if(cache_file.find(QDir::separator()) == -1) //guess they know what they are doing.. + cache_file.prepend(Option::output_dir + QDir::separator()); if((Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || Option::mkfile::do_deps || Option::mkfile::do_mocs) && !noIO()) { QPtrList<MakefileDependDir> deplist; deplist.setAutoDelete(TRUE); if((Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || Option::mkfile::do_deps) && doDepends()) { @@ -625,13 +700,13 @@ MakefileGenerator::init() incDirs += v["INCLUDEPATH"]; for(QStringList::Iterator it = incDirs.begin(); it != incDirs.end(); ++it) { QString r = (*it), l = Option::fixPathToLocalOS((*it)); deplist.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } - debug_msg(1, "Dependancy Directories: %s", incDirs.join(" :: ").latin1()); + debug_msg(1, "Dependency Directories: %s", incDirs.join(" :: ").latin1()); if(Option::output.name() != "-" && project->isActiveConfig("qmake_cache")) { QFile cachef(cache_file); if(cachef.open(IO_ReadOnly | IO_Translate)) { QFileInfo cachefi(cache_file); debug_msg(2, "Trying internal cache information: %s", cache_file.latin1()); QTextStream cachet(&cachef); @@ -680,13 +755,13 @@ MakefileGenerator::init() found = FALSE; break; } } } if(found) { - debug_msg(2, "Dependancies (cached): %s -> %s", file.latin1(), + debug_msg(2, "Dependencies (cached): %s -> %s", file.latin1(), files.join(" :: ").latin1()); findDependencies(file) = files; } } } else { void *found = cache_found_files[file]; @@ -740,12 +815,13 @@ MakefileGenerator::init() bool write_cache = FALSE, read_cache = QFile::exists(cache_file); for(int x = 0; sources[x] != QString::null; x++) { QStringList vpath, &l = v[sources[x]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { if(!(*val_it).isEmpty()) { QString file = Option::fixPathToLocalOS((*val_it)); + QStringList file_list(file); if(!QFile::exists(file)) { bool found = FALSE; if(QDir::isRelativePath(file)) { if(vpath.isEmpty()) vpath = v["VPATH_" + sources[x]] + v["VPATH"] + v["QMAKE_ABSOLUTE_SOURCE_PATH"] + v["DEPENDPATH"]; @@ -766,71 +842,80 @@ MakefileGenerator::init() } } if(!found) { QString dir, regex = (*val_it), real_dir; if(regex.findRev(Option::dir_sep) != -1) { dir = regex.left(regex.findRev(Option::dir_sep) + 1); - real_dir = fileFixify(Option::fixPathToLocalOS(dir), + real_dir = fileFixify(Option::fixPathToLocalOS(dir), QDir::currentDirPath(), Option::output_dir); regex = regex.right(regex.length() - dir.length()); } if(real_dir.isEmpty() || QFile::exists(real_dir)) { QDir d(real_dir, regex); if(!d.count()) { debug_msg(1, "%s:%d Failure to find %s in vpath (%s)", __FILE__, __LINE__, (*val_it).latin1(), vpath.join("::").latin1()); warn_msg(WarnLogic, "Failure to find: %s", (*val_it).latin1()); continue; } else { - (*val_it) = dir + d[0]; - for(int i = 1; i < (int)d.count(); i++) - l.insert(val_it, dir + d[i]); + file_list.clear(); + for(int i = 0; i < (int)d.count(); i++) { + file_list.append(dir + d[i]); + if(i == (int)d.count() - 1) + (*val_it) = dir + d[i]; + else + l.insert(val_it, dir + d[i]); + } } } else { debug_msg(1, "%s:%d Cannot match %s%c%s, as %s does not exist.", __FILE__, __LINE__, real_dir.latin1(), QDir::separator(), regex.latin1(), real_dir.latin1()); warn_msg(WarnLogic, "Failure to find: %s", (*val_it).latin1()); } } } - - QString val_file = fileFixify((*val_it)); - bool found_cache_moc = FALSE, found_cache_dep = FALSE; - if(read_cache && Option::output.name() != "-" && - project->isActiveConfig("qmake_cache")) { - if(!findDependencies(val_file).isEmpty()) - found_cache_dep = TRUE; - if(cache_found_files[(*val_it)] == (void *)2) - found_cache_moc = TRUE; - if(!found_cache_moc || !found_cache_dep) - write_cache = TRUE; - } - if(!found_cache_dep && sources[x] != "OBJECTS") { - debug_msg(5, "Looking for dependancies for %s", (*val_it).latin1()); - generateDependencies(deplist, (*val_it), doDepends()); - } - if(found_cache_moc) { - QString moc = findMocDestination(val_file); - if(!moc.isEmpty()) { - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); - cppit != Option::cpp_ext.end(); ++cppit) { - if(val_file.endsWith((*cppit))) { - QStringList &deps = findDependencies(val_file); - if(!deps.contains(moc)) - deps.append(moc); - break; + for(QStringList::Iterator file_it = file_list.begin(); + file_it != file_list.end(); ++file_it) { + QString file_list_file = fileFixify((*file_it)); + bool found_cache_moc = FALSE, found_cache_dep = FALSE; + if(read_cache && Option::output.name() != "-" && + project->isActiveConfig("qmake_cache")) { + if(!findDependencies(file_list_file).isEmpty()) + found_cache_dep = TRUE; + if(cache_found_files[(*file_it)] == (void *)2) + found_cache_moc = TRUE; + if(!found_cache_moc || !found_cache_dep) + write_cache = TRUE; + } + /* Do moc before dependency checking since some includes can come from + moc_*.cpp files */ + if(found_cache_moc) { + QString moc = findMocDestination(file_list_file); + if(!moc.isEmpty()) { + for(QStringList::Iterator cppit = Option::cpp_ext.begin(); + cppit != Option::cpp_ext.end(); ++cppit) { + if(file_list_file.endsWith((*cppit))) { + QStringList &deps = findDependencies(file_list_file); + if(!deps.contains(moc)) + deps.append(moc); + break; + } } } + } else if(mocAware() && (sources[x] == "SOURCES" || sources[x] == "HEADERS") && + (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || + Option::mkfile::do_mocs)) { + generateMocList((*file_it)); + } + if(!found_cache_dep && sources[x] != "OBJECTS") { + debug_msg(5, "Looking for dependencies for %s", (*file_it).latin1()); + generateDependencies(deplist, (*file_it), doDepends()); } - } else if(mocAware() && (sources[x] == "SOURCES" || sources[x] == "HEADERS") && - (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || - Option::mkfile::do_mocs)) { - generateMocList((*val_it)); } } } } if(project->isActiveConfig("qmake_cache") && (write_cache || !read_cache)) { QFile cachef(cache_file); @@ -850,17 +935,18 @@ MakefileGenerator::init() cachet << depKeyMap[it.key()] << " = " << it.data().join(" ") << endl; cachet << "[mocable]" << endl; QString mc, moc_sources[] = { QString("HEADERS"), QString("SOURCES"), QString::null }; for(int x = 0; moc_sources[x] != QString::null; x++) { QStringList &l = v[moc_sources[x]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { - if(!(*val_it).isEmpty()) { - mc = mocablesToMOC[(*val_it)]; + QString f = fileFixify((*val_it)); + if(!f.isEmpty()) { + mc = mocablesToMOC[f]; if(mc.isEmpty()) mc = "*qmake_ignore*"; - cachet << (*val_it) << " = " << mc << endl; + cachet << f << " = " << mc << endl; } } } cachef.close(); } } @@ -943,50 +1029,66 @@ MakefileGenerator::init() } v["OBJECTS"] += (v["YACCOBJECTS"] = createObjectList("YACCIMPLS")); } //UI files { + QStringList &includepath = project->variables()["INCLUDEPATH"]; if(!project->isEmpty("UI_DIR")) - project->variables()["INCLUDEPATH"].append(project->first("UI_DIR")); + includepath.append(project->first("UI_DIR")); else if(!project->isEmpty("UI_HEADERS_DIR")) - project->variables()["INCLUDEPATH"].append(project->first("UI_HEADERS_DIR")); + includepath.append(project->first("UI_HEADERS_DIR")); QStringList &decls = v["UICDECLS"], &impls = v["UICIMPLS"]; QStringList &l = v["FORMS"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString impl, decl; QFileInfo fi(Option::fixPathToLocalOS((*it))); if ( !project->isEmpty("UI_DIR") ) { impl = decl = project->first("UI_DIR"); QString d = fi.dirPath(); if( d == ".") d = QDir::currentDirPath(); - d = fileFixify(d); - if( !project->variables()["INCLUDEPATH"].contains(d)) - project->variables()["INCLUDEPATH"].append(d); + d = fileFixify(d, QDir::currentDirPath(), Option::output_dir); + if(!includepath.contains(d)) + includepath.append(d); } else { if(decl.isEmpty() && !project->isEmpty("UI_HEADERS_DIR")) decl = project->first("UI_HEADERS_DIR"); - if ( !decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") && !project->isEmpty("UI_SOURCES_DIR")) ) { + if(!decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") && + !project->isEmpty("UI_SOURCES_DIR")) ) { QString d = fi.dirPath(); if( d == ".") d = QDir::currentDirPath(); - d = fileFixify(d); - if( !project->variables()["INCLUDEPATH"].contains(d)) - project->variables()["INCLUDEPATH"].append(d); + d = fileFixify(d, QDir::currentDirPath(), Option::output_dir); + if(includepath.contains(d)) + includepath.append(d); } if(impl.isEmpty() && !project->isEmpty("UI_SOURCES_DIR")) impl = project->first("UI_SOURCES_DIR"); if(fi.dirPath() != ".") { if(impl.isEmpty()) impl = fi.dirPath() + Option::dir_sep; if(decl.isEmpty()) decl = fi.dirPath() + Option::dir_sep; } } - impl += fi.baseName(TRUE) + Option::cpp_ext.first(), + impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); + if(!impl.isEmpty()) + impl += Option::dir_sep; + impl += fi.baseName(TRUE) + Option::cpp_ext.first(); + if(Option::output_dir != QDir::currentDirPath() && + project->isEmpty("UI_DIR") && project->isEmpty("UI_HEADERS_DIR")) { + QString decl_fixed = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); + if(!includepath.contains(decl_fixed)) + includepath.append(decl_fixed); + if(!includepath.contains(decl)) + project->variables()["INCLUDEPATH"].append(decl); + } + decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); + if(!decl.isEmpty()) + decl += Option::dir_sep; decl += fi.baseName(TRUE) + Option::h_ext.first(); logicWarn(impl, "SOURCES"); logicWarn(decl, "HEADERS"); decls.append(decl); impls.append(impl); findDependencies(impl).append(decl); @@ -1027,15 +1129,15 @@ MakefileGenerator::init() } findDependencies(imgfile).append(fileFixify((*it))); } } v["OBJECTS"] += (v["IMAGEOBJECTS"] = createObjectList("QMAKE_IMAGE_COLLECTION")); } - - if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) - project->variables()["INCLUDEPATH"].append(Option::output_dir); + if(Option::output_dir != QDir::currentDirPath()) + project->variables()["INCLUDEPATH"].append(fileFixify(Option::output_dir, Option::output_dir, + Option::output_dir)); //moc files if ( mocAware() ) { if(!project->isEmpty("MOC_DIR")) project->variables()["INCLUDEPATH"].append(project->first("MOC_DIR")); v["OBJMOC"] = createObjectList("_HDRMOC") + createObjectList("_UIMOC"); @@ -1063,13 +1165,13 @@ MakefileGenerator::processPrlFile(QString &file) int ext = tmp.findRev('.'); if(ext != -1) tmp = tmp.left(ext); prl_file = tmp + Option::prl_ext; } prl_file = fileFixify(prl_file); - if(!QFile::exists(fileFixify(prl_file, QDir::currentDirPath(), Option::output_dir)) && + if(!QFile::exists(fileFixify(prl_file, QDir::currentDirPath(), Option::output_dir)) && project->isActiveConfig("qt")) { QString stem = prl_file, dir, extn; int slsh = stem.findRev('/'), hadlib = 0; if(slsh != -1) { dir = stem.left(slsh + 1); stem = stem.right(stem.length() - slsh - 1); @@ -1101,13 +1203,13 @@ MakefileGenerator::processPrlFile(QString &file) } else if(!real_prl_file.isEmpty() && QFile::exists(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir))) { project->variables()["QMAKE_PRL_INTERNAL_FILES"].append(prl_file); QMakeProject proj; debug_msg(1, "Processing PRL file: %s", real_prl_file.latin1()); if(!proj.read(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir), - QDir::currentDirPath())) { + QDir::currentDirPath(), TRUE)) { fprintf(stderr, "Error processing prl file: %s\n", real_prl_file.latin1()); } else { ret = TRUE; QMap<QString, QStringList> &vars = proj.variables(); for( QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) processPrlVariable(it.key(), it.data()); @@ -1193,12 +1295,14 @@ MakefileGenerator::writePrlFile(QTextStream &t) t << "QMAKE_PRL_SOURCE_DIR = " << project->first("QMAKE_ABSOLUTE_SOURCE_PATH") << endl; t << "QMAKE_PRL_TARGET = " << target << endl; if(!project->isEmpty("PRL_EXPORT_DEFINES")) t << "QMAKE_PRL_DEFINES = " << project->variables()["PRL_EXPORT_DEFINES"].join(" ") << endl; if(!project->isEmpty("CONFIG")) t << "QMAKE_PRL_CONFIG = " << project->variables()["CONFIG"].join(" ") << endl; + if(!project->isEmpty("VERSION")) + t << "QMAKE_PRL_VERSION = " << project->first("VERSION") << endl; if(project->isActiveConfig("staticlib") || project->isActiveConfig("explicitlib")) { QStringList libs; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"]; else libs << "QMAKE_LIBS"; //obvious one @@ -1225,25 +1329,24 @@ MakefileGenerator::write() int dot = prl.find('.'); if(dot != -1) prl = prl.left(dot); prl += Option::prl_ext; if(!project->isEmpty("DESTDIR")) prl.prepend(var("DESTDIR")); - QString local_prl = fileFixify(prl, QDir::currentDirPath(), Option::output_dir); - fixEnvVariables(local_prl); + QString local_prl = Option::fixPathToLocalOS(fileFixify(prl, QDir::currentDirPath(), Option::output_dir)); QFile ft(local_prl); if(ft.open(IO_WriteOnly)) { project->variables()["ALL_DEPS"].append(prl); project->variables()["QMAKE_INTERNAL_PRL_FILE"].append(prl); QTextStream t(&ft); writePrlFile(t); ft.close(); } } if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE && - project->isActiveConfig("link_prl")) //load up prl's + project->isActiveConfig("link_prl")) //load up prl's' processPrlFiles(); if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { QTextStream t(&Option::output); writeMakefile(t); @@ -1299,13 +1402,13 @@ MakefileGenerator::writeObj(QTextStream &t, const QString &obj, const QString &s } else { int dot = (*sit).findRev('.'); if(dot == -1 || ((*sit).left(dot) + Option::obj_ext != (*oit))) use_implicit_rule = FALSE; } } - if (!use_implicit_rule) { + if (!use_implicit_rule && !project->isEmpty(comp)) { QString p = var(comp); p.replace(stringSrc, (*sit)); p.replace(stringObj, (*oit)); t << "\n\t" << p; } t << endl << endl; @@ -1317,26 +1420,42 @@ void MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui) { QStringList &uil = project->variables()[ui]; for(QStringList::Iterator it = uil.begin(); it != uil.end(); it++) { QString deps = findDependencies((*it)).join(" \\\n\t\t"), decl, impl; { - QString tmp = (*it); + QString tmp = (*it), impl_dir, decl_dir; decl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::h_ext.first()); + decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); + int dlen = decl.findRev(Option::dir_sep) + 1; tmp = (*it); impl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::cpp_ext.first()); - int dlen = (*it).findRev(Option::dir_sep) + 1; + impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); + int ilen = decl.findRev(Option::dir_sep) + 1; if(!project->isEmpty("UI_DIR")) { + impl_dir = project->first("UI_DIR"); decl = project->first("UI_DIR") + decl.right(decl.length() - dlen); - impl = project->first("UI_DIR") + impl.right(impl.length() - dlen); + impl = project->first("UI_DIR") + impl.right(impl.length() - ilen); } else { - if(!project->isEmpty("UI_HEADERS_DIR")) + if(!project->isEmpty("UI_HEADERS_DIR")) { + decl_dir = project->first("UI_HEADERS_DIR"); decl = project->first("UI_HEADERS_DIR") + decl.right(decl.length() - dlen); - if(!project->isEmpty("UI_SOURCES_DIR")) - impl = project->first("UI_SOURCES_DIR") + impl.right(impl.length() - dlen); - } + } + if(!project->isEmpty("UI_SOURCES_DIR")) { + impl_dir = project->first("UI_SOURCES_DIR"); + impl = project->first("UI_SOURCES_DIR") + impl.right(impl.length() - ilen); + } + } + if(decl_dir.isEmpty()) + decl_dir = decl.left(dlen); + if(impl_dir.isEmpty()) + impl_dir = impl.left(ilen); + if(!impl_dir.isEmpty()) + createDir(Option::output_dir + Option::dir_sep + impl_dir); + if(!decl_dir.isEmpty() && decl_dir != impl_dir) + createDir(Option::output_dir + Option::dir_sep + decl_dir); } t << decl << ": " << (*it) << " " << deps << "\n\t" << "$(UIC) " << (*it) << " -o " << decl << endl << endl; QString mildDecl = decl; int k = mildDecl.findRev( Option::dir_sep ); @@ -1367,13 +1486,13 @@ MakefileGenerator::writeMocObj(QTextStream &t, const QString &obj, const QString } else { int dot = (*sit).findRev('.'); if(dot == -1 || ((*sit).left(dot) + Option::obj_ext != (*oit))) use_implicit_rule = FALSE; } } - if (!use_implicit_rule) { + if (!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) { QString p = var("QMAKE_RUN_CXX"); p.replace(stringSrc, (*sit)); p.replace(stringObj, (*oit)); t << "\n\t" << p; } t << endl << endl; @@ -1410,23 +1529,27 @@ MakefileGenerator::writeYaccSrc(QTextStream &t, const QString &src) default_out_h = project->first("QMAKE_YACC_HEADER"); if(!project->isEmpty("QMAKE_YACC_SOURCE")) default_out_c = project->first("QMAKE_YACC_SOURCE"); QString stringBase("$base"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi((*it)); - QString dir = fileFixify(Option::output_dir); + QString dir; + if(fi.dirPath() != ".") + dir = fi.dirPath() + Option::dir_sep; + dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; + QString impl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); QString decl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); QString yaccflags = "$(YACCFLAGS)", mangle = "y"; if(!project->isActiveConfig("yacc_no_name_mangle")) { mangle = fi.baseName(TRUE); yaccflags += " -p " + mangle; - } + } QString out_h = default_out_h, out_c = default_out_c; if(!mangle.isEmpty()) { out_h.replace(stringBase, mangle); out_c.replace(stringBase, mangle); } @@ -1449,24 +1572,27 @@ MakefileGenerator::writeLexSrc(QTextStream &t, const QString &src) QString default_out_c = "lex.$base.c"; if(!project->isEmpty("QMAKE_LEX_SOURCE")) default_out_c = project->first("QMAKE_LEX_SOURCE"); QString stringBase("$base"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi((*it)); - QString dir = fileFixify(Option::output_dir); + QString dir; + if(fi.dirPath() != ".") + dir = fi.dirPath() + Option::dir_sep; + dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; QString impl = dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); QString lexflags = "$(LEXFLAGS)", stub="yy"; if(!project->isActiveConfig("yacc_no_name_mangle")) { stub = fi.baseName(TRUE); lexflags += " -P" + stub; } QString out_c = default_out_c; - if(!stub.isEmpty()) + if(!stub.isEmpty()) out_c.replace(stringBase, stub); t << impl << ": " << (*it) << " " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" << ( "$(LEX) " + lexflags + " " ) << (*it) << "\n\t" << "-$(DEL_FILE) " << impl << " " << "\n\t" << "-$(MOVE) " << out_c << " " << impl << endl << endl; @@ -1491,13 +1617,13 @@ MakefileGenerator::writeImageObj(QTextStream &t, const QString &obj) } else { int dot = src.findRev('.'); if(dot == -1 || (src.left(dot) + Option::obj_ext != (*oit))) use_implicit_rule = FALSE; } } - if(!use_implicit_rule) { + if(!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) { QString p = var("QMAKE_RUN_CXX"); p.replace( stringSrc, src); p.replace( stringObj, (*oit)); t << "\n\t" << p; } t << endl << endl; @@ -1538,82 +1664,111 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) if(project->variables()[pvar].isEmpty()) { warn_msg(WarnLogic, "%s is not defined: install target not created\n", pvar.latin1()); continue; } bool do_default = TRUE; - QString target, dst="$(INSTALL_ROOT)" + Option::fixPathToTargetOS(project->variables()[pvar].first(), FALSE); + const QString root = "$(INSTALL_ROOT)"; + QString target, dst= fileFixify(project->variables()[pvar].first()); +#ifndef Q_WS_WIN if(dst.right(1) != Option::dir_sep) dst += Option::dir_sep; - QStringList tmp, &uninst = project->variables()[(*it) + ".uninstall"]; - //other - tmp = project->variables()[(*it) + ".extra"]; - if(!tmp.isEmpty()) { +#endif + QStringList tmp, &uninst = project->variables()[(*it) + ".uninstall"]; + //other + tmp = project->variables()[(*it) + ".extra"]; + if(!tmp.isEmpty()) { do_default = FALSE; if(!target.isEmpty()) - target += "\n\t"; - target += tmp.join(" "); - } - //masks - tmp = project->variables()[(*it) + ".files"]; - if(!tmp.isEmpty()) { + target += "\n\t"; + target += tmp.join(" "); + } + //masks + tmp = project->variables()[(*it) + ".files"]; + if(!tmp.isEmpty()) { if(!target.isEmpty()) - target += "\n"; + target += "\n"; do_default = FALSE; for(QStringList::Iterator wild_it = tmp.begin(); wild_it != tmp.end(); ++wild_it) { QString wild = Option::fixPathToLocalOS((*wild_it), FALSE), wild_var = fileFixify(wild); + QString dirstr = QDir::currentDirPath(), filestr = wild; + int slsh = filestr.findRev(Option::dir_sep); + if(slsh != -1) { + dirstr = filestr.left(slsh+1); + filestr = filestr.right(filestr.length() - slsh - 1); + } + if(dirstr.right(Option::dir_sep.length()) != Option::dir_sep) + dirstr += Option::dir_sep; if(QFile::exists(wild)) { //real file + QString file = wild; QFileInfo fi(wild); - target += QString("\t-") + (fi.isDir() ? "$(COPY_DIR)" : "$(COPY_FILE)") + - " \"" + Option::fixPathToTargetOS(fileFixify(wild), FALSE) + "\" \"" + fileFixify(dst) + "\"\n"; + if(!target.isEmpty()) + target += "\t"; + target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" + + Option::fixPathToTargetOS(fileFixify(wild), FALSE) + "\" \"" + root + dst + "\"\n"; if(!project->isActiveConfig("debug") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) - target += QString("\t") + var("QMAKE_STRIP") + " \"" + fileFixify(dst + wild) + "\"\n"; - uninst.append(QString("-$(DEL_FILE) -r") + " \"" + fileFixify(dst + wild) + "\""); + target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + filestr) + "\"\n"; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append( +#ifdef Q_WS_WIN + QString("-$(DEL_FILE)") +#else + QString("-$(DEL_FILE) -r") +#endif + + " \"" + root + fileFixify(dst + filestr) + "\""); continue; } - QString dirstr = QDir::currentDirPath(), f = wild; //wild - int slsh = f.findRev(Option::dir_sep); - if(slsh != -1) { - dirstr = f.left(slsh+1); - f = f.right(f.length() - slsh - 1); - } - if(dirstr.right(Option::dir_sep.length()) != Option::dir_sep) - dirstr += Option::dir_sep; - if(!uninst.isEmpty()) - uninst.append("\n\t"); - uninst.append(QString("-$(DEL_FILE) -r") + " " + fileFixify(dst + f) + ""); - - QDir dir(dirstr, f); + QDir dir(dirstr, filestr); //wild for(uint x = 0; x < dir.count(); x++) { QString file = dir[x]; if(file == "." || file == "..") //blah continue; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append( +#ifdef Q_WS_WIN + QString("-$(DEL_FILE)") +#else + QString("-$(DEL_FILE) -r") +#endif + + " \"" + root + fileFixify(dst + file) + "\""); QFileInfo fi(file); - target += QString("\t-") + (fi.isDir() ? "$(COPY_DIR)" : "$(COPY_FILE)") + - " \"" + Option::fixPathToTargetOS(fileFixify(dirstr + file), FALSE) + - "\" \"" + fileFixify(dst) + "\"\n"; + if(!target.isEmpty()) + target += "\t"; + target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" + + Option::fixPathToTargetOS(fileFixify(dirstr + file), FALSE) + + "\" \"" + root + fileFixify(dst) + "\"\n"; if(!project->isActiveConfig("debug") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) - target += QString("\t") + var("QMAKE_STRIP") + " \"" + fileFixify(dst + file) + "\"\n"; + target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + file) + "\"\n"; } } - } - //default? + } + //default? if(do_default) target = defaultInstall((*it)); if(!target.isEmpty()) { - t << "install_" << (*it) << ": " << "\n\t" - << "@test -d " << dst << " || mkdir -p " << dst << "\n\t" - << target << endl << endl; + t << "install_" << (*it) << ": " << "\n\t"; + const QStringList &dirs = project->variables()[pvar]; + for(QStringList::ConstIterator pit = dirs.begin(); pit != dirs.end(); ++pit) { + QString tmp_dst = fileFixify((*pit)); +#ifndef Q_WS_WIN + if(tmp_dst.right(1) != Option::dir_sep) + tmp_dst += Option::dir_sep; +#endif + t << mkdir_p_asstring(root+tmp_dst) << "\n\t"; + } + t << target << endl << endl; all_installs += QString("install_") + (*it) + " "; if(!uninst.isEmpty()) { t << "uninstall_" << (*it) << ": " << "\n\t" - << uninst.join(" ") << "\n\t" - << "-$(DEL_DIR) \"" << dst << "\"" << endl << endl; + << uninst.join("") << "\n\t" + << "-$(DEL_DIR) \"" << ( root + dst ) << "\"" << endl << endl; all_uninstalls += "uninstall_" + (*it) + " "; } t << endl; } else { debug_msg(1, "no definition for install %s: install target not created",(*it).latin1()); } @@ -1784,13 +1939,13 @@ QString MakefileGenerator::build_args() bool MakefileGenerator::writeHeader(QTextStream &t) { time_t foo = time(NULL); t << "#############################################################################" << endl; t << "# Makefile for building: " << var("TARGET") << endl; - t << "# Generated by qmake (" << qmake_version() << ") on: " << ctime(&foo); + t << "# Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: " << ctime(&foo); t << "# Project: " << fileFixify(project->projectFile()) << endl; t << "# Template: " << var("TEMPLATE") << endl; t << "# Command: " << build_args() << endl; t << "#############################################################################" << endl; t << endl; return TRUE; @@ -1799,13 +1954,13 @@ MakefileGenerator::writeHeader(QTextStream &t) //makes my life easier.. bool MakefileGenerator::writeMakeQmake(QTextStream &t) { QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.name())); - if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && + if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { QStringList files = fileFixify(Option::mkfile::project_files); t << project->first("QMAKE_INTERNAL_PRL_FILE") << ": " << "\n\t" << "@$(QMAKE) -prl " << buildArgs() << " " << files.join(" ") << endl; } @@ -1843,15 +1998,21 @@ MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, return ret; } QString MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const QString &in_d, bool force_fix) const { + if(file0.isEmpty()) + return file0; + QString key = file0; + if(!in_d.isEmpty() || !out_d.isEmpty() || force_fix) + key.prepend(in_d + "--" + out_d + "--" + QString::number((int)force_fix) + "-"); + if(fileFixed.contains(key)) + return fileFixed[key]; + QString file = file0; - if(file.isEmpty()) - return file; int depth = 4; if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { if(project && !project->isEmpty("QMAKE_PROJECT_DEPTH")) depth = project->first("QMAKE_PROJECT_DEPTH").toInt(); else if(Option::mkfile::cachefile_depth != -1) @@ -1887,21 +2048,32 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const if(!in_fi.convertToAbs()) in_dir = in_fi.filePath(); QFileInfo out_fi(out_dir); if(!out_fi.convertToAbs()) out_dir = out_fi.filePath(); } + QString in_canonical_dir = QDir(in_dir).canonicalPath(), + out_canonical_dir = QDir(out_dir).canonicalPath(); + if(!in_canonical_dir.isEmpty()) + in_dir = in_canonical_dir; + if(!out_canonical_dir.isEmpty()) + out_dir = out_canonical_dir; } if(out_dir != in_dir || !QDir::isRelativePath(qfile)) { if(QDir::isRelativePath(qfile)) { if(file.left(Option::dir_sep.length()) != Option::dir_sep && in_dir.right(Option::dir_sep.length()) != Option::dir_sep) file.prepend(Option::dir_sep); file.prepend(in_dir); } file = Option::fixPathToTargetOS(file, FALSE); + if(QFile::exists(file) && file == Option::fixPathToTargetOS(file, TRUE)) { + QString real_file = QDir(file).canonicalPath(); + if(!real_file.isEmpty()) + file = real_file; + } QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE); if(file == match_dir) { file = ""; } else if(file.startsWith(match_dir) && file.mid(match_dir.length(), Option::dir_sep.length()) == Option::dir_sep) { file = file.right(file.length() - (match_dir.length() + 1)); @@ -1926,15 +2098,18 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const } } } } } file = Option::fixPathToTargetOS(file, FALSE); + if(file.isEmpty()) + file = "."; if(!quote.isNull()) file = quote + file + quote; debug_msg(3, "Fixed %s :: to :: %s (%d)", orig_file.latin1(), file.latin1(), depth); + ((MakefileGenerator*)this)->fileFixed.insert(key, file); return file; } QString MakefileGenerator::cleanFilePath(const QString &file) const { @@ -2036,14 +2211,15 @@ MakefileGenerator::openOutput(QFile &file) const } //Factory thing #include "unixmake.h" -#include "borland_bmake.h" #include "msvc_nmake.h" +#include "borland_bmake.h" +#include "mingw_make.h" #include "msvc_dsp.h" #include "msvc_vcproj.h" #include "metrowerks_xml.h" #include "pbuilder_pbx.h" #include "projectgenerator.h" @@ -2058,25 +2234,27 @@ MakefileGenerator::create(QMakeProject *proj) if(gen.isEmpty()) { fprintf(stderr, "No generator specified in config file: %s\n", proj->projectFile().latin1()); } else if(gen == "UNIX") { mkfile = new UnixMakefileGenerator(proj); } else if(gen == "MSVC") { - // Visual Studio =< v6.0 + // Visual Studio =< v6.0 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1) mkfile = new DspMakefileGenerator(proj); else mkfile = new NmakeMakefileGenerator(proj); } else if(gen == "MSVC.NET") { - // Visual Studio >= v7.0 + // Visual Studio >= v7.0 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1) mkfile = new VcprojGenerator(proj); else mkfile = new NmakeMakefileGenerator(proj); } else if(gen == "BMAKE") { mkfile = new BorlandMakefileGenerator(proj); + } else if(gen == "MINGW") { + mkfile = new MingwMakefileGenerator(proj); } else if(gen == "METROWERKS") { mkfile = new MetrowerksMakefileGenerator(proj); } else if(gen == "PROJECTBUILDER") { mkfile = new ProjectBuilderMakefileGenerator(proj); } else { fprintf(stderr, "Unknown generator specified: %s\n", gen.latin1()); diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 1d19d98..4fdabe8 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -44,13 +44,13 @@ class MakefileGenerator { QString spec; bool init_opath_already, init_already, moc_aware, no_io; QStringList createObjectList(const QString &var); QString build_args(); - QMap<QString, QString> depHeuristics, depKeyMap; + QMap<QString, QString> depHeuristics, depKeyMap, fileFixed; QMap<QString, QString> mocablesToMOC, mocablesFromMOC; QMap<QString, QStringList> depends; protected: void writeObj(QTextStream &, const QString &obj, const QString &src); void writeUicSrc(QTextStream &, const QString &ui); @@ -65,22 +65,22 @@ protected: protected: QMakeProject *project; class MakefileDependDir { public: - MakefileDependDir(QString r, QString l) : real_dir(r), local_dir(l) { } + MakefileDependDir(const QString &r, const QString &l) : real_dir(r), local_dir(l) { } QString real_dir, local_dir; }; - bool generateDependencies(QPtrList<MakefileDependDir> &dirs, QString x, bool recurse); + bool generateDependencies(QPtrList<MakefileDependDir> &dirs, const QString &x, bool recurse); QString buildArgs(); QString specdir(); QString cleanFilePath(const QString &file) const; - bool generateMocList(QString fn); + bool generateMocList(const QString &fn); QString findMocSource(const QString &moc_file) const; QString findMocDestination(const QString &src_file) const; QStringList &findDependencies(const QString &file); void setNoIO(bool o); diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index 5ff6250..1515216 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -39,12 +39,28 @@ #include "option.h" #include <qdir.h> #include <qfile.h> #include <qfileinfo.h> #include <qregexp.h> +QString project_builtin_regx() //calculate the builtin regular expression.. +{ + QString ret; + QStringList builtin_exts(".c"); + builtin_exts << Option::ui_ext << Option::yacc_ext << Option::lex_ext << ".ts"; + builtin_exts += Option::h_ext + Option::cpp_ext; + for(QStringList::Iterator ext_it = builtin_exts.begin(); + ext_it != builtin_exts.end(); ++ext_it) { + if(!ret.isEmpty()) + ret += "; "; + ret += QString("*") + (*ext_it); + } + return ret; +} + + ProjectGenerator::ProjectGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE) { } void @@ -64,27 +80,19 @@ ProjectGenerator::init() //figure out target if(Option::output.name() == "-" || Option::output.name().isEmpty()) v["TARGET"] = QStringList("unknown"); //the scary stuff if(project->first("TEMPLATE_ASSIGN") != "subdirs") { - QString builtin_regex; - { //calculate the builtin regular expression.. - QStringList builtin_exts(".c"); - builtin_exts << Option::ui_ext << Option::yacc_ext << Option::lex_ext; - builtin_exts += Option::h_ext + Option::cpp_ext; - for(QStringList::Iterator ext_it = builtin_exts.begin(); - ext_it != builtin_exts.end(); ++ext_it) { - if(!builtin_regex.isEmpty()) - builtin_regex += "; "; - builtin_regex += QString("*") + (*ext_it); - } - } + QString builtin_regex = project_builtin_regx(); QStringList dirs = Option::projfile::project_dirs; - if(Option::projfile::do_pwd) + if(Option::projfile::do_pwd) { + if(!v["INCLUDEPATH"].contains(".")) + v["INCLUDEPATH"] += "."; dirs.prepend(QDir::currentDirPath()); + } for(QStringList::Iterator pd = dirs.begin(); pd != dirs.end(); pd++) { QString dir, regex; bool add_depend = FALSE; if(QFile::exists((*pd))) { QFileInfo fi((*pd)); @@ -137,15 +145,14 @@ ProjectGenerator::init() file_count++; } } } if(add_depend && !dir.isEmpty() && !v["DEPENDPATH"].contains(dir)) { QFileInfo fi(dir); - if(fi.absFilePath() != QDir::currentDirPath()) { + if(fi.absFilePath() != QDir::currentDirPath()) v["DEPENDPATH"] += fileFixify(dir); - } } } } if(!file_count) { //shall we try a subdir? QStringList dirs = Option::projfile::project_dirs; if(Option::projfile::do_pwd) @@ -238,18 +245,25 @@ ProjectGenerator::init() QStringList &l = v[srcs[i]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { if(generateDependencies(deplist, (*val_it), TRUE)) { QStringList &tmp = findDependencies((*val_it)); if(!tmp.isEmpty()) { for(QStringList::Iterator dep_it = tmp.begin(); dep_it != tmp.end(); ++dep_it) { - QString file_no_path = (*dep_it).right( - (*dep_it).length() - ((*dep_it).findRev(Option::dir_sep)+1)); + QString file_dir = (*dep_it).section(Option::dir_sep, 0, -2), + file_no_path = (*dep_it).section(Option::dir_sep, -1); + if(!file_dir.isEmpty()) { + for(MakefileDependDir *mdd = deplist.first(); mdd; mdd = deplist.next()) { + if(mdd->local_dir == file_dir && !v["INCLUDEPATH"].contains(mdd->real_dir)) + v["INCLUDEPATH"] += mdd->real_dir; + } + } if(no_qt_files && file_no_path.find(QRegExp("^q[a-z_0-9].h$")) != -1) no_qt_files = FALSE; QString h_ext; - for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { + for(QStringList::Iterator hit = Option::h_ext.begin(); + hit != Option::h_ext.end(); ++hit) { if((*dep_it).endsWith((*hit))) { h_ext = (*hit); break; } } if(!h_ext.isEmpty()) { @@ -257,17 +271,19 @@ ProjectGenerator::init() QString qhdr = (*dep_it).lower(); if(file_no_path == "qthread.h") addConfig("thread"); } for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { - QString src((*dep_it).left((*dep_it).length() - h_ext.length()) + (*cppit)); + QString src((*dep_it).left((*dep_it).length() - h_ext.length()) + + (*cppit)); if(QFile::exists(src)) { bool exists = FALSE; QStringList &srcl = v["SOURCES"]; - for(QStringList::Iterator src_it = srcl.begin(); src_it != srcl.end(); ++src_it) { + for(QStringList::Iterator src_it = srcl.begin(); + src_it != srcl.end(); ++src_it) { if((*src_it).lower() == src.lower()) { exists = TRUE; break; } } if(!exists) @@ -334,20 +350,22 @@ ProjectGenerator::writeMakefile(QTextStream &t) t << endl << "# Directories" << "\n" << getWritableVar("SUBDIRS"); } else { t << getWritableVar("TARGET") << getWritableVar("CONFIG", FALSE) << getWritableVar("CONFIG_REMOVE", FALSE) - << getWritableVar("DEPENDPATH") << endl; + << getWritableVar("DEPENDPATH") + << getWritableVar("INCLUDEPATH") << endl; t << "# Input" << "\n"; t << getWritableVar("HEADERS") << getWritableVar("INTERFACES") << getWritableVar("LEXSOURCES") << getWritableVar("YACCSOURCES") - << getWritableVar("SOURCES"); + << getWritableVar("SOURCES") + << getWritableVar("TRANSLATIONS"); } for(it = Option::after_user_vars.begin(); it != Option::after_user_vars.end(); ++it) t << (*it) << endl; return TRUE; } @@ -400,12 +418,14 @@ ProjectGenerator::addFile(QString file) else if(file.endsWith(".c")) where = "SOURCES"; else if(file.endsWith(Option::lex_ext)) where = "LEXSOURCES"; else if(file.endsWith(Option::yacc_ext)) where = "YACCSOURCES"; + else if(file.endsWith(".ts")) + where = "TRANSLATIONS"; } QString newfile = fileFixify(file); if(!where.isEmpty() && !project->variables()[where].contains(file)) { project->variables()[where] += newfile; return TRUE; diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 7df95b2..e274481 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -69,24 +69,23 @@ UnixMakefileGenerator::init() if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1) project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all"); return; /* subdirs is done */ } if( project->isEmpty("QMAKE_EXTENSION_SHLIB") ) { - QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 ); - if ( os == "cygwin" ) { - project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dll" ); - } else { + if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) { project->variables()["QMAKE_EXTENSION_SHLIB"].append( "so" ); + } else { + project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dll" ); } } if( project->isEmpty("QMAKE_COPY_FILE") ) project->variables()["QMAKE_COPY_FILE"].append( "$(COPY) -p" ); if( project->isEmpty("QMAKE_COPY_DIR") ) project->variables()["QMAKE_COPY_DIR"].append( "$(COPY) -pR" ); - //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET + //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET if(!project->isEmpty("TARGET")) { QString targ = project->first("TARGET"); int slsh = QMAX(targ.findRev('/'), targ.findRev(Option::dir_sep)); if(slsh != -1) { if(project->isEmpty("DESTDIR")) project->values("DESTDIR").append(""); @@ -135,13 +134,13 @@ UnixMakefileGenerator::init() project->isActiveConfig("dll")) project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PREBIND"]; if(!project->isEmpty("QMAKE_INCDIR")) project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"]; if(!project->isEmpty("QMAKE_LIBDIR")) { if ( !project->isEmpty("QMAKE_RPATH") ) - project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"), + project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"), " " + var("QMAKE_RPATH"), ""); project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue( "QMAKE_LIBDIR", "-L", " -L", "" ); } if ( extern_libs && (project->isActiveConfig("qt") || project->isActiveConfig("opengl")) ) { if(configs.findIndex("x11lib") == -1) configs.append("x11lib"); @@ -163,56 +162,56 @@ UnixMakefileGenerator::init() project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; if ( !project->isActiveConfig("debug") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); if ( !is_qt ) { if ( !project->isEmpty("QMAKE_LIBDIR_QT") ) { if ( !project->isEmpty("QMAKE_RPATH") ) - project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"), + project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"), " " + var("QMAKE_RPATH"), ""); project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", "-L", " -L", ""); } if (project->isActiveConfig("thread") && !project->isEmpty("QMAKE_LIBS_QT_THREAD")) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; } } - if ( project->isActiveConfig("thread") ) { - if(project->isActiveConfig("qt")) - project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); - if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) - project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"]; - if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) - project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"]; - project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_THREAD"]; - project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_THREAD"]; - if(!project->isEmpty("QMAKE_LFLAGS_THREAD")) - project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_THREAD"]; - } if ( project->isActiveConfig("opengl") ) { project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"]; - if(!project->isEmpty("QMAKE_LIBDIR_OPENGL")) + if(!project->isEmpty("QMAKE_LIBDIR_OPENGL")) project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_OPENGL", "-L", " -L", ""); if ( is_qt ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; } if(project->isActiveConfig("global_init_link_order")) project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; - if ( project->isActiveConfig("x11sm") ) - project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11SM"]; - if ( project->isActiveConfig("dylib") ) - project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_DYNLOAD"]; if ( project->isActiveConfig("x11inc") ) project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_X11"]; if ( project->isActiveConfig("x11lib") ) { if(!project->isEmpty("QMAKE_LIBDIR_X11")) project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_X11", "-L", " -L", ""); project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11"]; } + if ( project->isActiveConfig("x11sm") ) + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11SM"]; + if ( project->isActiveConfig("dylib") ) + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_DYNLOAD"]; + if ( project->isActiveConfig("thread") ) { + if(project->isActiveConfig("qt")) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); + if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"]; + if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"]; + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_THREAD"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_THREAD"]; + if(!project->isEmpty("QMAKE_LFLAGS_THREAD")) + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_THREAD"]; + } if ( project->isActiveConfig("moc") ) setMocAware(TRUE); if ( project->isEmpty("QMAKE_RUN_CC") ) project->variables()["QMAKE_RUN_CC"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src"); if ( project->isEmpty("QMAKE_RUN_CC_IMP") ) project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<"); @@ -337,29 +336,113 @@ UnixMakefileGenerator::uniqueSetLFlags(const QStringList &list1, QStringList &li } } else { unique = (list2.findIndex((*it)) == -1); } } else if(QFile::exists((*it))) { unique = (list2.findIndex((*it)) == -1); - } + } if(unique) ret.append((*it)); } return ret; } void UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) { - if(var == "QMAKE_PRL_LIBS") + if(var == "QMAKE_PRL_LIBS") project->variables()["QMAKE_CURRENT_PRL_LIBS"] += uniqueSetLFlags(l, project->variables()["QMAKE_LIBS"]); else MakefileGenerator::processPrlVariable(var, l); } +bool +UnixMakefileGenerator::findLibraries() +{ + QPtrList<MakefileDependDir> libdirs; + libdirs.setAutoDelete(TRUE); + const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; + for(int i = 0; !lflags[i].isNull(); i++) { + QStringList &l = project->variables()[lflags[i]]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QString stub, dir, extn, opt = (*it).stripWhiteSpace(); + if(opt.startsWith("-")) { + if(opt.startsWith("-L")) { + QString r = opt.right(opt.length() - 2), l = r; + fixEnvVariables(l); + libdirs.append(new MakefileDependDir(r.replace("\"",""), + l.replace("\"",""))); + } else if(opt.startsWith("-l")) { + stub = opt.mid(2); + } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) { + if(opt.length() > 11) { + opt = opt.mid(11); + } else { + ++it; + opt = (*it); + } + extn = ""; + dir = "/System/Library/Frameworks/" + opt + ".framework/"; + stub = opt; + } + } else { + extn = dir = ""; + stub = opt; + int slsh = opt.findRev(Option::dir_sep); + if(slsh != -1) { + dir = opt.left(slsh); + stub = opt.mid(slsh+1); + } + QRegExp stub_reg("^.*lib(" + stub + "[^./=]*)\\.(.*)$"); + if(stub_reg.exactMatch(stub)) { + stub = stub_reg.cap(1); + extn = stub_reg.cap(2); + } + } + if(!stub.isEmpty()) { + const QString modifs[] = { "-mt", QString::null }; + for(int modif = 0; !modifs[modif].isNull(); modif++) { + bool found = FALSE; + QStringList extens; + if(!extn.isNull()) + extens << extn; + else + extens << project->variables()["QMAKE_EXTENSION_SHLIB"].first() << "a"; + for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { + if(dir.isNull()) { + QString lib_stub; + for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { + if(QFile::exists(mdd->local_dir + Option::dir_sep + "lib" + stub + + modifs[modif] + "." + (*extit))) { + lib_stub = stub + modifs[modif]; + break; + } + } + if(!lib_stub.isNull()) { + (*it) = "-l" + lib_stub; + found = TRUE; + break; + } + } else { + if(QFile::exists("lib" + stub + modifs[modif] + "." + (*extit))) { + (*it) = "lib" + stub + modifs[modif] + "." + (*extit); + found = TRUE; + break; + } + } + } + if(found) + break; + } + } + } + } + return FALSE; +} + void UnixMakefileGenerator::processPrlFiles() { QDict<void> processed; QPtrList<MakefileDependDir> libdirs; libdirs.setAutoDelete(TRUE); @@ -399,13 +482,13 @@ UnixMakefileGenerator::processPrlFiles() } else { ++it; opt = (*it); } QString prl = "/System/Library/Frameworks/" + opt + ".framework/" + opt + Option::prl_ext; - if(processPrlFile(prl)) + if(processPrlFile(prl)) ret = TRUE; l_out.append("-framework"); } if(!opt.isEmpty()) l_out.append(opt); l_out += uniqueSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"], l_out); @@ -431,18 +514,19 @@ QString UnixMakefileGenerator::defaultInstall(const QString &t) { if(t != "target" || project->first("TEMPLATE") == "subdirs") return QString(); bool resource = FALSE; + const QString root = "$(INSTALL_ROOT)"; QStringList &uninst = project->variables()[t + ".uninstall"]; - QString ret, destdir=fileFixify(project->first("DESTDIR")); + QString ret, destdir=project->first("DESTDIR"); QString targetdir = Option::fixPathToTargetOS(project->first("target.path"), FALSE); if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep) destdir += Option::dir_sep; - targetdir = "$(INSTALL_ROOT)" + Option::fixPathToTargetOS(targetdir, FALSE); + targetdir = fileFixify(targetdir); if(targetdir.right(1) != Option::dir_sep) targetdir += Option::dir_sep; QStringList links; QString target="$(TARGET)"; if(project->first("TEMPLATE") == "app") { @@ -455,41 +539,42 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } else if(project->first("TEMPLATE") == "lib") { if(project->isActiveConfig("create_prl") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { QString dst_prl = project->first("QMAKE_INTERNAL_PRL_FILE"); int slsh = dst_prl.findRev('/'); if(slsh != -1) dst_prl = dst_prl.right(dst_prl.length() - slsh - 1); - dst_prl = targetdir + dst_prl; - ret += "-$(COPY) " + project->first("QMAKE_INTERNAL_PRL_FILE") + " " + dst_prl; + dst_prl = root + targetdir + dst_prl; + ret += "-$(COPY) \"" + project->first("QMAKE_INTERNAL_PRL_FILE") + "\" \"" + dst_prl + "\""; if(!uninst.isEmpty()) uninst.append("\n\t"); uninst.append("-$(DEL_FILE) \"" + dst_prl + "\""); } - QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 ); - if ( os != "cygwin" ) { + if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) { if ( !project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") ) { - if ( os == "hpux" ) { - links << "$(TARGET0)"; - } else { + if ( project->isEmpty("QMAKE_HPUX_SHLIB") ) { links << "$(TARGET0)" << "$(TARGET1)" << "$(TARGET2)"; + } else { + links << "$(TARGET0)"; } } } } QString src_targ = target; if(!destdir.isEmpty()) src_targ = Option::fixPathToTargetOS(destdir + target, FALSE); - QString dst_targ = fileFixify(targetdir + target); + QString dst_targ = root + fileFixify(targetdir + target); if(!ret.isEmpty()) ret += "\n\t"; ret += QString(resource ? "-$(COPY_DIR)" : "-$(COPY)") + " \"" + src_targ + "\" \"" + dst_targ + "\""; - if(!project->isEmpty("QMAKE_STRIP")) { + if(!project->isActiveConfig("debug") && !project->isEmpty("QMAKE_STRIP")) { ret += "\n\t-" + var("QMAKE_STRIP"); + if(!project->isEmpty("QMAKE_STRIPFLAGS_LIB") && project->first("TEMPLATE") == "lib") + ret += " " + var("QMAKE_STRIPFLAGS_LIB"); if(resource) - ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)"; + ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)\""; else ret += " \"" + dst_targ + "\""; } if(!uninst.isEmpty()) uninst.append("\n\t"); if(resource) @@ -503,18 +588,17 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } else if(Option::target_mode == Option::TARG_UNIX_MODE || Option::target_mode == Option::TARG_MACX_MODE) { QString link = Option::fixPathToTargetOS(destdir + (*it), FALSE); int lslash = link.findRev(Option::dir_sep); if(lslash != -1) link = link.right(link.length() - (lslash + 1)); - QString dst_link = fileFixify(targetdir + link); + QString dst_link = root + fileFixify(targetdir + link); ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\""; if(!uninst.isEmpty()) uninst.append("\n\t"); uninst.append("-$(DEL_FILE) \"" + dst_link + "\""); } } } return ret; } - diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index e889dcc..3d00214 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -52,12 +52,13 @@ public: protected: virtual bool doDepends() const { return !include_deps && MakefileGenerator::doDepends(); } virtual QString defaultInstall(const QString &); virtual void processPrlVariable(const QString &, const QStringList &); virtual void processPrlFiles(); + virtual bool findLibraries(); virtual void init(); void writeMakeParts(QTextStream &); void writeSubdirs(QTextStream &, bool=TRUE); private: diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 9bb6f6b..7fbb9f4 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -76,15 +76,14 @@ void UnixMakefileGenerator::writeMakeParts(QTextStream &t) { QString deps = fileFixify(Option::output.name()), prl; bool do_incremental = (project->isActiveConfig("incremental") && !project->variables()["QMAKE_INCREMENTAL"].isEmpty() && (!project->variables()["QMAKE_APP_FLAG"].isEmpty() || - !project->isActiveConfig("staticlib"))), + !project->isActiveConfig("staticlib"))), src_incremental=FALSE, moc_incremental=FALSE; - QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 ); t << "####### Compiler, tools and options" << endl << endl; t << "CC = "; if (project->isActiveConfig("thread") && ! project->variables()["QMAKE_CC_THREAD"].isEmpty()) t << var("QMAKE_CC_THREAD") << endl; @@ -105,13 +104,20 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << varGlue("DEFINES","-D"," -D","") << endl; t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; t << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl; t << "YACCFLAGS= " << var("QMAKE_YACCFLAGS") << endl; - t << "INCPATH = " << varGlue("INCLUDEPATH","-I", " -I", "") << " -I" << specdir() << endl; + t << "INCPATH = " << "-I" << specdir(); + if(!project->isActiveConfig("no_include_pwd")) { + QString pwd = fileFixify(QDir::currentDirPath()); + if(pwd.isEmpty()) + pwd = "."; + t << " -I" << pwd; + } + t << varGlue("INCLUDEPATH"," -I", " -I", "") << endl; if(!project->isActiveConfig("staticlib")) { t << "LINK = "; if (project->isActiveConfig("thread") && ! project->variables()["QMAKE_LINK_THREAD"].isEmpty()) t << var("QMAKE_LINK_THREAD") << endl; @@ -133,13 +139,14 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "COPY_FILE= " << var("QMAKE_COPY_FILE") << endl; t << "COPY_DIR = " << var("QMAKE_COPY_DIR") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "SYMLINK = " << var("QMAKE_SYMBOLIC_LINK") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; - t << "PRO = " << fileFixify(project->projectFile() )<< endl; + t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; t << endl; t << "####### Output directory" << endl << endl; if (! project->variables()["OBJECTS_DIR"].isEmpty()) t << "OBJECTS_DIR = " << var("OBJECTS_DIR") << endl; else @@ -209,30 +216,28 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } } else { t << "OBJMOC = " << objMoc << endl; } if(do_incremental && !moc_incremental && !src_incremental) do_incremental = FALSE; - t << "DIST = " << varList("DISTFILES") << endl; - t << "PRO = " << fileFixify(project->projectFile()) << endl; + t << "DIST = " << valList(fileFixify(project->variables()["DISTFILES"])) << endl; t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl; t << "DESTDIR = " << var("DESTDIR") << endl; t << "TARGET = " << var("TARGET") << endl; if(project->isActiveConfig("plugin") ) { t << "TARGETD = " << var("TARGET") << endl; } else if (!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty()) { t << "TARGETA = " << var("TARGETA") << endl; - if (os == "hpux") { - t << "TARGETD = " << var("TARGET_x") << endl; - t << "TARGET0 = " << var("TARGET_") << endl; - } - else { + if (project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "TARGETD = " << var("TARGET_x.y.z") << endl; t << "TARGET0 = " << var("TARGET_") << endl; t << "TARGET1 = " << var("TARGET_x") << endl; t << "TARGET2 = " << var("TARGET_x.y") << endl; + } else { + t << "TARGETD = " << var("TARGET_x") << endl; + t << "TARGET0 = " << var("TARGET_") << endl; } } t << endl; // blasted incldues QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"]; @@ -258,13 +263,13 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) cmd += " -I" + project->first("QMAKE_ABSOLUTE_SOURCE_PATH") + " "; cmd += " $(INCPATH) " + varGlue("DEPENDPATH", "-I", " -I", ""); QString odir; if(!project->variables()["OBJECTS_DIR"].isEmpty()) odir = project->first("OBJECTS_DIR"); - t << "###### Dependancies" << endl << endl; + t << "###### Dependencies" << endl << endl; t << odir << ".deps/%.d: %.cpp\n\t" << "@echo Creating depend for $<" << "\n\t" << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t" << "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl; t << odir << ".deps/%.d: %.c\n\t" @@ -383,26 +388,28 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)"; } t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; //real target - t << var("TARGET") << ": " << " " << incr_deps << " " << var("TARGETDEPS") << "\n\t"; + t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps + << " " << var("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; if(!project->isEmpty("QMAKE_PRE_LINK")) t << var("QMAKE_PRE_LINK") << "\n\t"; t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(LIBS)"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else { t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; - t << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("TARGETDEPS") << "\n\t"; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << var("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; if(!project->isEmpty("QMAKE_PRE_LINK")) t << var("QMAKE_PRE_LINK") << "\n\t"; t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"; if(!project->isEmpty("QMAKE_POST_LINK")) @@ -457,19 +464,19 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } t << "all: " << " " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " << var("DESTDIR_TARGET") << endl << endl; //real target - t << var("DESTDIR_TARGET") << ": " << incr_deps << " $(SUBLIBS) " << - var("TARGETDEPS"); + t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") << " " + << incr_deps << " $(SUBLIBS) " << var("POST_TARGETDEPS"); } else { t << "all: " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " << var("DESTDIR_TARGET") << endl << endl; - t << var("DESTDIR_TARGET") << ": $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) " << - var("TARGETDEPS"); + t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) " << var("POST_TARGETDEPS"); } if(!destdir.isEmpty()) t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir; if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" << var("QMAKE_PRE_LINK"); @@ -480,26 +487,13 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!destdir.isEmpty()) t << "\n\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR"); if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK") << "\n\t"; t << endl << endl; - } else if ( os == "hpux" ) { - t << "\n\t" - << "-$(DEL_FILE) $(TARGET) $(TARGET0)" << "\n\t" - << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"; - t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)"); - if(!destdir.isEmpty()) - t << "\n\t" - << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t" - << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t" - << "-$(MOVE) $(TARGET) $(TARGET0) " << var("DESTDIR"); - if(!project->isEmpty("QMAKE_POST_LINK")) - t << "\n\t" << var("QMAKE_POST_LINK"); - t << endl << endl; - } else { + } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "\n\t" << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t" << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"; t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t" << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t" << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)"); @@ -510,64 +504,78 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET1)\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET2)\n\t" << "-$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) " << var("DESTDIR"); if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; + } else { + t << "\n\t" + << "-$(DEL_FILE) $(TARGET) $(TARGET0)" << "\n\t" + << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"; + t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)"); + if(!destdir.isEmpty()) + t << "\n\t" + << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t" + << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t" + << "-$(MOVE) $(TARGET) $(TARGET0) " << var("DESTDIR"); + if(!project->isEmpty("QMAKE_POST_LINK")) + t << "\n\t" << var("QMAKE_POST_LINK"); + t << endl << endl; } t << endl << endl; if (! project->isActiveConfig("plugin")) { t << "staticlib: $(TARGETA)" << endl << endl; - t << "$(TARGETA): $(UICDECLS) $(OBJECTS) $(OBJMOC)"; + t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC)"; if(do_incremental) t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"; - t << var("TARGETDEPS") << "\n\t" + t << var("POST_TARGETDEPS") << "\n\t" << "-$(DEL_FILE) $(TARGETA) " << "\n\t" << var("QMAKE_AR_CMD"); if(do_incremental) t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\n\t" << "$(RANLIB) $(TARGETA)"; t << endl << endl; } } else { - t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) " + t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) " << varGlue("QMAKE_AR_SUBLIBS", var("DESTDIR"), " " + var("DESTDIR"), "") << "\n\n" << "staticlib: " << var("DESTDIR") << "$(TARGET)" << "\n\n"; if(project->isEmpty("QMAKE_AR_SUBLIBS")) { - t << var("DESTDIR") << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(TARGETDEPS) " << "\n\t"; + t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("POST_TARGETDEPS") << "\n\t"; if(!project->isEmpty("DESTDIR")) { QString destdir = project->first("DESTDIR"); t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; } t << "-$(DEL_FILE) $(TARGET)" << "\n\t" << var("QMAKE_AR_CMD") << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\t" << var("QMAKE_POST_LINK") << "\n"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\t" << "$(RANLIB) $(TARGET)" << "\n"; - if(!project->isEmpty("DESTDIR")) + if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)" << "\n" << "\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR") << "\n"; } else { - int cnt = 0, max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(); + int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(); QStringList objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"], libs = project->variables()["QMAKE_AR_SUBLIBS"]; libs.prepend("$(TARGET)"); - for(QStringList::Iterator libit = libs.begin(), objit = objs.begin(); + for(QStringList::Iterator libit = libs.begin(), objit = objs.begin(); libit != libs.end(); ++libit) { QStringList build; - for(cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) + for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) build << (*objit); QString ar; if((*libit) == "$(TARGET)") { - t << var("DESTDIR") << "$(TARGET): $(UICDECLS) " << " $(TARGETDEPS) " - << valList(build) << "\n\t"; + t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") + << " $(UICDECLS) " << var("POST_TARGETDEPS") << valList(build) << "\n\t"; ar = project->variables()["QMAKE_AR_CMD"].first(); - ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)", + ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)", build.join(" ")); } else { t << (*libit) << ": " << valList(build) << "\n\t"; ar = "$(AR) " + (*libit) + " " + build.join(" "); } if(!project->isEmpty("DESTDIR")) { @@ -577,30 +585,30 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "-$(DEL_FILE) " << (*libit) << "\n\t" << ar << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\t" << var("QMAKE_POST_LINK") << "\n"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\t" << "$(RANLIB) " << (*libit) << "\n"; - if(!project->isEmpty("DESTDIR")) + if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << (*libit) << "\n" << "\t" << "-$(MOVE) " << (*libit) << " " << var("DESTDIR") << "\n"; } } t << endl << endl; } t << "mocables: $(SRCMOC)" << endl << endl; if(!project->isActiveConfig("no_mocdepend")) { //this is an implicity depend on moc, so it will be built if necesary, however - //moc itself shouldn't have this dependancy - this is a little kludgy but it is + //moc itself shouldn't have this dependency - this is a little kludgy but it is //better than the alternative for now. QString moc = project->first("QMAKE_MOC"), target = project->first("TARGET"); fixEnvVariables(target); fixEnvVariables(moc); - if(target != moc) + if(target != moc) t << "$(MOC): \n\t" << "( cd $(QTDIR)/src/moc ; $(MAKE) )" << endl << endl; } writeMakeQmake(t); @@ -640,23 +648,23 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("TRANSLATIONS")) t << "$(COPY_FILE) --parents " << var("TRANSLATIONS") << " " << ddir_c << Option::dir_sep << " && "; if(!project->isEmpty("FORMS")) { QStringList &forms = project->variables()["FORMS"], ui_headers; for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { QString ui_h = fileFixify((*formit) + Option::h_ext.first()); - if(QFile::exists(ui_h) ) + if(QFile::exists(ui_h) ) ui_headers << ui_h; } if(!ui_headers.isEmpty()) t << "$(COPY_FILE) --parents " << val(ui_headers) << " " << ddir_c << Option::dir_sep << " && "; } t << "( cd `dirname " << ddir_c << "` && " << "$(TAR) " << var("QMAKE_ORIG_TARGET") << ".tar " << ddir << " && " << "$(GZIP) " << var("QMAKE_ORIG_TARGET") << ".tar ) && " << "$(MOVE) `dirname " << ddir_c << "`" << Option::dir_sep << var("QMAKE_ORIG_TARGET") << ".tar.gz . && " - << "$(DEL_DIR) " << ddir_c + << "$(DEL_FILE) -r " << ddir_c << endl << endl; QString clean_targets; if(mocAware()) { t << "mocclean:" << "\n"; if(!objMoc.isEmpty() || !srcMoc.isEmpty() || moc_incremental) { @@ -674,12 +682,51 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if (!var("UICIMPLS").isEmpty() || !var("UICDECLS").isEmpty()) { t << "\t-$(DEL_FILE) $(UICIMPLS) $(UICDECLS)" << "\n"; clean_targets += " uiclean"; } t << endl; + t << "yaccclean:" << "\n"; + if(!var("YACCSOURCES").isEmpty()) { + QStringList clean, &l = project->variables()["YACCSOURCES"]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QFileInfo fi((*it)); + QString dir; + if(fi.dirPath() != ".") + dir = fi.dirPath() + Option::dir_sep; + dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); + if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) + dir += Option::dir_sep; + clean << dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); + clean << dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); + } + if(!clean.isEmpty()) { + t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n"; + clean_targets += " yaccclean"; + } + } + + t << "lexclean:" << "\n"; + if(!var("LEXSOURCES").isEmpty()) { + QStringList clean, &l = project->variables()["LEXSOURCES"]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QFileInfo fi((*it)); + QString dir; + if(fi.dirPath() != ".") + dir = fi.dirPath() + Option::dir_sep; + dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); + if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) + dir += Option::dir_sep; + clean << dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); + } + if(!clean.isEmpty()) { + t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n"; + clean_targets += " lexclean"; + } + } + if(do_incremental) { t << "incrclean:" << "\n"; if(src_incremental) t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n"; if(moc_incremental) t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n'; @@ -707,14 +754,18 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << var(QString("MAKELIB") + (*it)) << endl << endl; } QString destdir = project->first("DESTDIR"); if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep) destdir += Option::dir_sep; - t << "distclean: " << "clean\n\t" - << "-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << "$(TARGET)" << "\n"; + t << "distclean: " << "clean\n"; + if(project->first("TEMPLATE") == "app" && + project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) + t << "\t-$(DEL_FILE) -r " << destdir.section(Option::dir_sep, 0, -4) << "\n"; + else + t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << "$(TARGET)" << "\n"; if(!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty() && !project->isActiveConfig("plugin")) t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " << destdir << "$(TARGET2) $(TARGETA)" << "\n"; t << endl << endl; @@ -803,13 +854,13 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) if(ofile.findRev(Option::dir_sep) != -1) ofile = ofile.right(ofile.length() - ofile.findRev(Option::dir_sep) -1); t << "MAKEFILE = " << var("MAKEFILE") << endl; t << "QMAKE = " << var("QMAKE") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "SUBTARGETS = "; // subdirectory targets are sub-directory - for( it.toFirst(); it.current(); ++it) + for( it.toFirst(); it.current(); ++it) t << " \\\n\t\t" << it.current()->target; t << endl << endl; t << "first: all\n\nall: " << ofile << " $(SUBTARGETS)" << endl << endl; // generate target rules for( it.toFirst(); it.current(); ++it) { @@ -832,22 +883,22 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) } if (project->isActiveConfig("ordered")) { // generate dependencies for( it.toFirst(); it.current(); ) { QString tar = it.current()->target; ++it; - if (it.current()) + if (it.current()) t << it.current()->target << ": " << tar << endl; } t << endl; } writeMakeQmake(t); if(project->isEmpty("SUBDIRS")) { - t << "all qmake_all distclean install uiclean mocclean clean: FORCE" << endl; + t << "all qmake_all distclean install uiclean mocclean lexclean yaccclean clean: FORCE" << endl; } else { t << "all: $(SUBTARGETS)" << endl; t << "qmake_all:"; for( it.toFirst(); it.current(); ++it) { t << " "; if(!(*it)->directory.isEmpty()) @@ -855,17 +906,17 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) t << (*it)->makefile; } for( it.toFirst(); it.current(); ++it) { t << "\n\t ( "; if(!(*it)->directory.isEmpty()) t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; - t << "grep \"^qmake_all:\" " << (*it)->makefile + t << "grep \"^qmake_all:\" " << (*it)->makefile << " && $(MAKE) -f " << (*it)->makefile << " qmake_all" << "; ) || true"; } t << endl; - t << "clean uninstall install uiclean mocclean: qmake_all FORCE"; + t << "clean uninstall install uiclean mocclean lexclean yaccclean: qmake_all FORCE"; for( it.toFirst(); it.current(); ++it) { t << "\n\t ( "; if(!(*it)->directory.isEmpty()) t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; t << "$(MAKE) -f " << (*it)->makefile << " $@" << "; ) || true"; } @@ -903,49 +954,50 @@ void UnixMakefileGenerator::init2() project->variables()["QMAKE_LFLAGS_SHAPP"] += project->variables()["QMAKE_LFLAGS_SHLIB"]; if(!project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty()) project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET"); } #endif project->variables()["TARGET"].first().prepend(project->first("DESTDIR")); + if ( !project->variables()["QMAKE_CYGWIN_EXE"].isEmpty() ) + project->variables()["TARGET_EXT"].append(".exe"); } else if ( project->isActiveConfig("staticlib") ) { project->variables()["TARGET"].first().prepend("lib"); project->variables()["TARGET"].first() += ".a"; if(project->variables()["QMAKE_AR_CMD"].isEmpty()) project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGET) $(OBJECTS) $(OBJMOC)"); } else { project->variables()["TARGETA"].append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a"); if ( !project->variables()["QMAKE_AR_CMD"].isEmpty() ) project->variables()["QMAKE_AR_CMD"].first().replace("(TARGET)","(TARGETA)"); else project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGETA) $(OBJECTS) $(OBJMOC)"); - QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 ); if( project->isActiveConfig("plugin") ) { project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB")); if(project->isActiveConfig("lib_version_first")) project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + - project->first("VER_MAJ") + "." + + project->first("VER_MAJ") + "." + project->first("QMAKE_EXTENSION_SHLIB")); else project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ")); project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"]; if(project->isActiveConfig("qt")) project->variables()["DEFINES"].append("QT_PLUGIN"); - } else if ( os == "hpux" ) { + } else if ( !project->isEmpty("QMAKE_HPUX_SHLIB") ) { project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".sl"); if(project->isActiveConfig("lib_version_first")) - project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." + + project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." + project->first("TARGET")); else - project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + + project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ")); project->variables()["TARGET"] = project->variables()["TARGET_x"]; - } else if ( os == "aix" ) { + } else if ( !project->isEmpty("QMAKE_AIX_SHLIB") ) { project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".a"); if(project->isActiveConfig("lib_version_first")) { project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("QMAKE_EXTENSION_SHLIB")); project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." + @@ -1008,14 +1060,21 @@ void UnixMakefileGenerator::init2() } if(project->isEmpty("QMAKE_LN_SHLIB")) project->variables()["QMAKE_LN_SHLIB"].append("ln -s"); project->variables()["DESTDIR_TARGET"].append("$(TARGET)"); if ( !project->variables()["DESTDIR"].isEmpty() ) project->variables()["DESTDIR_TARGET"].first().prepend(project->first("DESTDIR")); - if ( !project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty() && !project->variables()["TARGET_x"].isEmpty() ) - project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET_x"); + if ( !project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty()) { + if(project->isActiveConfig("plugin")) { + if(!project->variables()["TARGET"].isEmpty() ) + project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET"); + } else { + if(!project->variables()["TARGET_x"].isEmpty() ) + project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET_x"); + } + } if ( project->variables()["QMAKE_LINK_SHLIB_CMD"].isEmpty() ) project->variables()["QMAKE_LINK_SHLIB_CMD"].append( "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"); } if(project->isEmpty("QMAKE_SYMBOLIC_LINK")) project->variables()["QMAKE_SYMBOLIC_LINK"].append("ln -sf"); diff --git a/qmake/generators/win32/borland_bmake.cpp b/qmake/generators/win32/borland_bmake.cpp index ae7b47b..26eea88 100644 --- a/qmake/generators/win32/borland_bmake.cpp +++ b/qmake/generators/win32/borland_bmake.cpp @@ -129,12 +129,14 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "RES_FILE = " << varList("RES_FILE") << endl; t << "COPY_FILE = " << var("QMAKE_COPY") << endl; t << "COPY_DIR = " << var("QMAKE_COPY") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; + t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; t << endl; t << "####### Files" << endl << endl; t << "HEADERS = " << varList("HEADERS") << endl; t << "SOURCES = " << varList("SOURCES") << endl; t << "OBJECTS = " << varList("OBJECTS") << endl; @@ -147,31 +149,39 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "TARGET = " << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT")) << endl; t << endl; t << "####### Implicit rules" << endl << endl; - t << ".SUFFIXES: .cpp .cxx .cc .c" << endl << endl; - t << ".cpp.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".cxx.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".cc.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".c.obj:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + t << ".SUFFIXES: .c"; + QStringList::Iterator cppit; + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << " " << (*cppit); + t << endl << endl; + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".c" << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; t << "####### Build rules" << endl << endl; t << "all: " << varGlue("ALL_DEPS",""," "," ") << " $(TARGET)" << endl << endl; - t << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("TARGETDEPS"); + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << var("POST_TARGETDEPS"); if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { t << "\n\t" << "$(LINK) @&&|" << "\n\t" << "$(LFLAGS) $(OBJECTS) $(OBJMOC),$(TARGET),,$(LIBS),$(DEF_FILE),$(RES_FILE)"; } else { t << "\n\t-del $(TARGET)" << "\n\t" << "$(LIB) $(TARGET) @&&|" << " \n+" << project->variables()["OBJECTS"].join(" \\\n+") << " \\\n+" << project->variables()["OBJMOC"].join(" \\\n+"); } t << endl << "|" << endl; + + if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) + t << "\t" <<var("QMAKE_POST_LINK") << endl; + if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { t << "\n\t" << "-copy $(TARGET) " << *dlldir; } } @@ -210,21 +220,18 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "clean:\n" << varGlue("OBJECTS","\t-del ","\n\t-del ","") << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","") << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","") << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","") << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","") - << "\n\t-del $(TARGET)" << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","") << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ",""); if ( project->isActiveConfig("activeqt")) { t << ("\n\t-del tmp\\" + targetfilename + ".*"); t << "\n\t-del tmp\\dump.*"; } - if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) - t << "\n\t-del " << var("DLLDESTDIR") << "\\" << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first(); if(!project->isEmpty("IMAGES")) t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); // blasted user defined targets QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { @@ -241,12 +248,16 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) } t << "\n\n" << targ << ":" << deps << "\n\t" << cmd; } t << endl << endl; + + t << "distclean: clean" + << "\n\t-del $(TARGET)" + << endl << endl; } void BorlandMakefileGenerator::init() { if(init_flag) @@ -361,13 +372,13 @@ BorlandMakefileGenerator::init() project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt"); if ( hver == -1 ) - hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt"); + hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qtmt"); if(hver != -1) { QString ver; ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) (*libit).replace(QRegExp("qt(mt)?\\.lib"), ver); @@ -423,12 +434,34 @@ BorlandMakefileGenerator::init() } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; } + if ( project->isActiveConfig("stl") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; + } + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + if ( project->isActiveConfig("thread") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_RTMT"]; } else { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_RT"]; } if ( project->isActiveConfig("moc") ) { @@ -449,13 +482,13 @@ BorlandMakefileGenerator::init() fprintf(stderr, "Both .rc and .res file specified.\n"); fprintf(stderr, "Please specify one of them, not both."); exit(666); } project->variables()["RES_FILE"] = project->variables()["RC_FILE"]; project->variables()["RES_FILE"].first().replace(".rc",".res"); - project->variables()["TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; } MakefileGenerator::init(); if ( !project->variables()["VERSION"].isEmpty()) { QStringList l = QStringList::split('.', project->first("VERSION")); project->variables()["VER_MAJ"].append(l[0]); project->variables()["VER_MIN"].append(l[1]); @@ -471,7 +504,6 @@ BorlandMakefileGenerator::init() tdsPostfix = ".tds"; } project->variables()["QMAKE_CLEAN"].append( project->first("DESTDIR") + project->first("TARGET") + tdsPostfix ); } } - diff --git a/qmake/generators/win32/borland_bmake.h b/qmake/generators/win32/borland_bmake.h index 90f8229..5ffed58 100644 --- a/qmake/generators/win32/borland_bmake.h +++ b/qmake/generators/win32/borland_bmake.h @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -31,14 +31,14 @@ ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef __BORLANDMAKE_H__ -#define __BORLANDMAKE_H__ +#ifndef __BORLAND_BMAKE_H__ +#define __BORLAND_BMAKE_H__ #include "winmakefile.h" class BorlandMakefileGenerator : public Win32MakefileGenerator { bool init_flag; @@ -52,8 +52,7 @@ public: ~BorlandMakefileGenerator(); }; inline BorlandMakefileGenerator::~BorlandMakefileGenerator() { } - -#endif /* __BORLANDMAKE_H__ */ +#endif /* __BORLAND_BMAKE_H__ */ diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp new file mode 100644 index 0000000..7f58a55 --- a/dev/null +++ b/qmake/generators/win32/mingw_make.cpp @@ -0,0 +1,524 @@ +/****************************************************************************
+** $Id$
+**
+** Definition of ________ class.
+**
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+**
+** This file is part of the network module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mingw_make.h"
+#include "option.h"
+#include <qregexp.h>
+#include <qdir.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+MingwMakefileGenerator::MingwMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE)
+{
+ Option::obj_ext = ".o";
+}
+
+bool
+MingwMakefileGenerator::writeMakefile(QTextStream &t)
+{
+ writeHeader(t);
+ if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
+ t << "all clean:" << "\n\t"
+ << "@echo \"Some of the required modules ("
+ << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
+ << "@echo \"Skipped.\"" << endl << endl;
+ writeMakeQmake(t);
+ return TRUE;
+ }
+
+ if(project->first("TEMPLATE") == "app" ||
+ project->first("TEMPLATE") == "lib") {
+ writeMingwParts(t);
+ return MakefileGenerator::writeMakefile(t);
+ }
+ else if(project->first("TEMPLATE") == "subdirs") {
+ writeSubDirs(t);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+MingwMakefileGenerator::writeMingwParts(QTextStream &t)
+{
+ t << "####### Compiler, tools and options" << endl << endl;
+ t << "CC = " << var("QMAKE_CC") << endl;
+ t << "CXX = " << var("QMAKE_CXX") << endl;
+ t << "LEX = " << var("QMAKE_LEX") << endl;
+ t << "YACC = " << var("QMAKE_YACC") << endl;
+ t << "CFLAGS = " << var("QMAKE_CFLAGS") << " "
+ << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
+ << varGlue("DEFINES","-D"," -D","") << endl;
+ t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " "
+ << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
+ << varGlue("DEFINES","-D"," -D","") << endl;
+ t << "LEXFLAGS =" << var("QMAKE_LEXFLAGS") << endl;
+ t << "YACCFLAGS =" << var("QMAKE_YACCFLAGS") << endl;
+
+ t << "INCPATH = ";
+ QStringList &incs = project->variables()["INCLUDEPATH"];
+ for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
+ QString inc = (*incit);
+ inc.replace(QRegExp("\\\\$"), "\\\\");
+ inc.replace(QRegExp("\""), "");
+ t << " -I" << inc ;
+ }
+ t << " -I" << specdir()
+ << endl;
+ if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
+ t << "LINK = " << var("QMAKE_LINK") << endl;
+ t << "LFLAGS = ";
+ if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() )
+ t << varGlue("QMAKE_LIBDIR","-L",";","") << " ";
+ t << var("QMAKE_LFLAGS") << endl;
+ t << "LIBS = " << var("QMAKE_LIBS").replace(QRegExp("(\\slib|^lib)")," -l") << endl;
+ }
+ else {
+ t << "LIB = " << var("QMAKE_LIB") << endl;
+ }
+ t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") :
+ Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl;
+ t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") :
+ Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl;
+ t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") :
+ Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl;
+ t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") :
+ Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl;
+ t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") :
+ Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl;
+ t << "ZIP = " << var("QMAKE_ZIP") << endl;
+ t << "DEF_FILE = " << varList("DEF_FILE") << endl;
+ t << "COPY_FILE = " << var("QMAKE_COPY") << endl;
+ t << "COPY_DIR = " << var("QMAKE_COPY") << endl;
+ t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
+ t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl;
+ t << "MOVE = " << var("QMAKE_MOVE") << endl;
+ t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl;
+ t << "MKDIR = " << var("QMAKE_MKDIR") << endl;
+ t << endl;
+
+ t << "####### Output directory" << endl << endl;
+ if (! project->variables()["OBJECTS_DIR"].isEmpty())
+ t << "OBJECTS_DIR = " << var("OBJECTS_DIR").replace(QRegExp("\\\\$"),"") << endl;
+ else
+ t << "OBJECTS_DIR = . " << endl;
+ if (! project->variables()["MOC_DIR"].isEmpty())
+ t << "MOC_DIR = " << var("MOC_DIR").replace(QRegExp("\\\\$"),"") << endl;
+ else
+ t << "MOC_DIR = . " << endl;
+ t << endl;
+
+ t << "####### Files" << endl << endl;
+ t << "HEADERS = " << varList("HEADERS") << endl;
+ t << "SOURCES = " << varList("SOURCES") << endl;
+// t << "OBJECTS = " << varList("OBJECTS").replace(QRegExp("\\.obj"),".o") << endl;
+ t << "OBJECTS = " << varList("OBJECTS") << endl;
+ t << "FORMS = " << varList("FORMS") << endl;
+ t << "UICDECLS = " << varList("UICDECLS") << endl;
+ t << "UICIMPLS = " << varList("UICIMPLS") << endl;
+ t << "SRCMOC = " << varList("SRCMOC") << endl;
+ t << "OBJMOC = " << varList("OBJMOC") << endl;
+// t << "OBJMOC = " << varList("OBJMOC").replace(QRegExp("\\.obj"),".o") << endl;
+ t << "DIST = " << varList("DISTFILES") << endl;
+ t << "TARGET = ";
+ if( !project->variables()[ "DESTDIR" ].isEmpty() )
+ t << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT"));
+ else
+ t << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
+ t << endl;
+ t << endl;
+
+ t << "####### Implicit rules" << endl << endl;
+ t << ".SUFFIXES: .cpp .cxx .cc .C .c" << endl << endl;
+ t << ".cpp.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
+ t << ".cxx.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
+ t << ".cc.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
+ t << ".C.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
+ t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
+
+ t << "####### Build rules" << endl << endl;
+ t << "all: " << "$(OBJECTS_DIR) " << "$(MOC_DIR) " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl;
+ t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) "
+ << var("POST_TARGETDEPS");
+ if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
+ t << "\n\t" << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)";
+ } else {
+ t << "\n\t" << "$(LIB) $(TARGET) $(OBJECTS) $(OBJMOC)";
+ }
+
+ if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) {
+ QStringList dlldirs = project->variables()["DLLDESTDIR"];
+ for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) {
+ t << "\n\t" << "copy $(TARGET) " << *dlldir;
+ }
+ }
+ QString targetfilename = project->variables()["TARGET"].first();
+ if(project->isActiveConfig("activeqt")) {
+ QString version = project->variables()["VERSION"].first();
+ if ( version.isEmpty() )
+ version = "1.0";
+
+ if ( project->isActiveConfig("dll")) {
+ t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version);
+ t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
+ t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
+ t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" );
+ } else {
+ t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version);
+ t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
+ t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
+ t << "\n\t" << "-$(TARGET) -regserver";
+ }
+ }
+ t << endl << endl;
+
+ if(!project->variables()["RC_FILE"].isEmpty()) {
+ t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t"
+ << var("QMAKE_RC") << " -i " << var("RC_FILE") << " -o " << var("RC_FILE").replace(QRegExp("\\.rc"),".o") << endl << endl;
+ }
+ project->variables()["RES_FILE"].first().replace(QRegExp("\\.rc"),".o");
+
+ t << "mocables: $(SRCMOC)" << endl << endl;
+
+ t << "$(OBJECTS_DIR):" << "\n\t"
+ << "@if not exist $(OBJECTS_DIR) mkdir $(OBJECTS_DIR)" << endl << endl;
+
+ t << "$(MOC_DIR):" << "\n\t"
+ << "@if not exist $(MOC_DIR) mkdir $(MOC_DIR)" << endl << endl;
+
+ writeMakeQmake(t);
+
+ t << "dist:" << "\n\t"
+ << "$(ZIP) " << var("PROJECT") << ".zip "
+ << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl;
+
+ t << "clean:"
+ << varGlue("OBJECTS","\n\t-del ","\n\t-del ","").replace(QRegExp("\\.obj"),".o")
+ << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","")
+ << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","").replace(QRegExp("\\.obj"),".o")
+ << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","")
+ << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","")
+ << "\n\t-del $(TARGET)"
+ << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","")
+ << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ","");
+ if ( project->isActiveConfig("activeqt")) {
+ t << ("\n\t-del tmp\\" + targetfilename + ".*");
+ t << "\n\t-del tmp\\dump.*";
+ }
+ if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty())
+ t << "\n\t-del " << var("DLLDESTDIR") << "\\" << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
+ if(!project->isEmpty("IMAGES"))
+ t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", "");
+
+ // blasted user defined targets
+ QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"];
+ for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) {
+ QString targ = var((*it) + ".target"),
+ cmd = var((*it) + ".commands"), deps;
+ if(targ.isEmpty())
+ targ = (*it);
+ QStringList &deplist = project->variables()[(*it) + ".depends"];
+ for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
+ QString dep = var((*dep_it) + ".target");
+ if(dep.isEmpty())
+ dep = (*dep_it);
+ deps += " " + dep;
+ }
+ t << "\n\n" << targ << ":" << deps << "\n\t"
+ << cmd;
+ }
+
+ t << endl << endl;
+}
+
+
+void
+MingwMakefileGenerator::init()
+{
+ if(init_flag)
+ return;
+ init_flag = TRUE;
+
+ /* this should probably not be here, but I'm using it to wrap the .t files */
+ if(project->first("TEMPLATE") == "app")
+ project->variables()["QMAKE_APP_FLAG"].append("1");
+ else if(project->first("TEMPLATE") == "lib")
+ project->variables()["QMAKE_LIB_FLAG"].append("1");
+ else if(project->first("TEMPLATE") == "subdirs") {
+ MakefileGenerator::init();
+ if(project->variables()["MAKEFILE"].isEmpty())
+ project->variables()["MAKEFILE"].append("Makefile");
+ if(project->variables()["QMAKE"].isEmpty())
+ project->variables()["QMAKE"].append("qmake");
+ return;
+ }
+
+ bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX);
+ project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
+
+ // LIBS defined in Profile comes first for gcc
+ project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
+
+ QString targetfilename = project->variables()["TARGET"].first();
+ QStringList &configs = project->variables()["CONFIG"];
+ if (project->isActiveConfig("qt") && project->isActiveConfig("shared"))
+ project->variables()["DEFINES"].append("QT_DLL");
+ if (project->isActiveConfig("qt_dll"))
+ if(configs.findIndex("qt") == -1) configs.append("qt");
+ if ( project->isActiveConfig("qt") ) {
+ if ( project->isActiveConfig( "plugin" ) ) {
+ project->variables()["CONFIG"].append("dll");
+ if(project->isActiveConfig("qt"))
+ project->variables()["DEFINES"].append("QT_PLUGIN");
+ }
+ if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) &&
+ ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 ||
+ project->variables()["DEFINES"].findIndex("QT_DLL") != -1) ||
+ (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) {
+ project->variables()["QMAKE_QT_DLL"].append("1");
+ if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() )
+ project->variables()["CONFIG"].append("dll");
+ }
+ if ( project->isActiveConfig("thread") )
+ project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT");
+ if ( project->isActiveConfig("accessibility" ) )
+ project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
+ if ( project->isActiveConfig("tablet") )
+ project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
+ }
+ if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
+ project->variables()["CONFIG"].remove("staticlib");
+ project->variables()["QMAKE_APP_OR_DLL"].append("1");
+ } else {
+ project->variables()["CONFIG"].append("staticlib");
+ }
+ if ( project->isActiveConfig("warn_off") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"];
+ } else if ( project->isActiveConfig("warn_on") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"];
+ }
+ if ( project->isActiveConfig("debug") ) {
+ if ( project->isActiveConfig("thread") ) {
+ // use the DLL RT even here
+ if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"];
+ } else {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"];
+ }
+ }
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"];
+ } else {
+ if ( project->isActiveConfig("thread") ) {
+ if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"];
+ } else {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"];
+ }
+ }
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"];
+ }
+
+ if ( !project->variables()["QMAKE_INCDIR"].isEmpty())
+ project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
+ if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") )
+ project->variables()["CONFIG"].append("windows");
+ if ( project->isActiveConfig("qt") ) {
+ project->variables()["CONFIG"].append("moc");
+ project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
+ project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
+ if ( !project->isActiveConfig("debug") )
+ project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG");
+ if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
+ if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) {
+ project->variables()["DEFINES"].append("QT_MAKEDLL");
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"];
+ }
+ } else {
+ if(project->isActiveConfig("thread"))
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
+ else
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
+ if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
+ int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt");
+ if ( hver == -1 )
+ hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt");
+ if(hver != -1) {
+ QString ver;
+ ver.sprintf("libqt-%s" QTDLL_POSTFIX "%d.a", (project->isActiveConfig("thread") ? "-mt" : ""), hver);
+ QStringList &libs = project->variables()["QMAKE_LIBS"];
+// @@@HGTODO maybe we must change the replace regexp if we understand what's going on
+ for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit)
+ (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver);
+ }
+ }
+ if ( project->isActiveConfig( "activeqt" ) ) {
+ project->variables().remove("QMAKE_LIBS_QT_ENTRY");
+ project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib";
+ if ( project->isActiveConfig( "dll" ) )
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
+ }
+ if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) {
+ project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"];
+ }
+ }
+ }
+ if ( project->isActiveConfig("opengl") ) {
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
+ }
+ if ( project->isActiveConfig("dll") ) {
+ project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"];
+ project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"];
+ project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"];
+ project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"];
+ if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) {
+ project->variables()["TARGET_EXT"].append(
+ QStringList::split('.',project->first("VERSION")).join("") + ".dll");
+ } else {
+ project->variables()["TARGET_EXT"].append(".dll");
+ }
+ } else {
+ project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"];
+ project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"];
+ project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"];
+ project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"];
+ if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
+ project->variables()["TARGET_EXT"].append(".exe");
+ } else {
+ project->variables()["TARGET_EXT"].append(".a");
+ project->variables()["QMAKE_LFLAGS"].append("-static");
+ if(project->variables()["TARGET"].first().left(3) != "lib")
+ project->variables()["TARGET"].first().prepend("lib");
+ }
+ }
+ if ( project->isActiveConfig("windows") ) {
+ if ( project->isActiveConfig("console") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
+ } else {
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"];
+ }
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"];
+ } else {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
+ }
+
+ if ( project->isActiveConfig("moc") )
+ setMocAware(TRUE);
+ project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ',
+ "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH");
+ QStringList &l = project->variables()["QMAKE_FILETAGS"];
+ for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
+ QStringList &gdmf = project->variables()[(*it)];
+ for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner)
+ (*inner) = Option::fixPathToTargetOS((*inner), FALSE);
+ }
+
+ if ( project->isActiveConfig("dll") )
+ project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--out-implib,") + project->first("DESTDIR") + "\\lib"+ project->first("TARGET") + ".a");
+
+ if ( !project->variables()["DEF_FILE"].isEmpty() )
+ project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--output-def,") + project->first("DEF_FILE"));
+// if(!project->isActiveConfig("incremental"))
+// project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no"));
+
+#if 0
+ if ( !project->variables()["VERSION"].isEmpty() ) {
+ QString version = project->variables()["VERSION"][0];
+ int firstDot = version.find( "." );
+ QString major = version.left( firstDot );
+ QString minor = version.right( version.length() - firstDot - 1 );
+ minor.replace( ".", "" );
+ project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor );
+ }
+#endif
+ if ( !project->variables()["RC_FILE"].isEmpty()) {
+ if ( !project->variables()["RES_FILE"].isEmpty()) {
+ fprintf(stderr, "Both .rc and .res file specified.\n");
+ fprintf(stderr, "Please specify one of them, not both.");
+ exit(666);
+ }
+ project->variables()["RES_FILE"] = project->variables()["RC_FILE"];
+ project->variables()["RES_FILE"].first().replace(".rc",".o");
+ project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"];
+ }
+ if ( !project->variables()["RES_FILE"].isEmpty())
+ project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"];
+
+ MakefileGenerator::init();
+ if ( !project->variables()["VERSION"].isEmpty()) {
+ QStringList l = QStringList::split('.', project->first("VERSION"));
+ project->variables()["VER_MAJ"].append(l[0]);
+ project->variables()["VER_MIN"].append(l[1]);
+ }
+ if(project->isActiveConfig("dll")) {
+ project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") +"lib" + project->first("TARGET") + ".a");
+ }
+}
+
+void
+MingwMakefileGenerator::writeSubDirs(QTextStream &t)
+{
+ QString qs ;
+ QTextStream ts (&qs, IO_WriteOnly) ;
+ Win32MakefileGenerator::writeSubDirs( ts ) ;
+ QRegExp rx("(\\n\\tcd [^\\n\\t]+)(\\n\\t.+)\\n\\t@cd ..") ;
+ rx.setMinimal(true);
+ int pos = 0 ;
+ while ( -1 != (pos = rx.search( qs, pos)))
+ {
+ QString qsMatch = rx.cap(2);
+ qsMatch.replace("\n\t"," && \\\n\t");
+ qs.replace(pos+rx.cap(1).length(), rx.cap(2).length(), qsMatch );
+ pos += (rx.cap(1).length()+qsMatch.length());
+ }
+ t << qs ;
+}
diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h new file mode 100644 index 0000000..c00bf1b --- a/dev/null +++ b/qmake/generators/win32/mingw_make.h @@ -0,0 +1,58 @@ +/****************************************************************************
+** $Id$
+**
+** Definition of ________ class.
+**
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+**
+** This file is part of the network module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef __MINGW_MAKE_H__
+#define __MINGW_MAKE_H__
+
+#include "winmakefile.h"
+
+class MingwMakefileGenerator : public Win32MakefileGenerator
+{
+ bool init_flag;
+ void writeMingwParts(QTextStream &);
+ void writeSubDirs(QTextStream &t) ;
+
+ bool writeMakefile(QTextStream &);
+ void init();
+
+public:
+ MingwMakefileGenerator(QMakeProject *p);
+ ~MingwMakefileGenerator();
+
+};
+
+inline MingwMakefileGenerator::~MingwMakefileGenerator()
+{ }
+
+#endif /* __MINGW_MAKE_H__ */
diff --git a/qmake/generators/win32/msvc_dsp.cpp b/qmake/generators/win32/msvc_dsp.cpp index 8b08c78..3fa0496 100644 --- a/qmake/generators/win32/msvc_dsp.cpp +++ b/qmake/generators/win32/msvc_dsp.cpp @@ -505,12 +505,36 @@ DspMakefileGenerator::init() { if(init_flag) return; QStringList::Iterator it; init_flag = TRUE; + const bool thread = project->isActiveConfig("thread"); + + if ( project->isActiveConfig("stl") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; + } + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "vcapp" ) project->variables()["QMAKE_APP_FLAG"].append("1"); else if(project->first("TEMPLATE") == "vclib") project->variables()["QMAKE_LIB_FLAG"].append("1"); if ( project->variables()["QMAKESPEC"].isEmpty() ) @@ -565,23 +589,23 @@ DspMakefileGenerator::init() if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { project->variables()["DEFINES"].append("QT_MAKEDLL"); project->variables()["QMAKE_LFLAGS"].append("/base:\"0x39D00000\""); } } else { - if(project->isActiveConfig("thread")) + if( thread ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt"); if ( hver == -1 ) hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt"); if(hver != -1) { QString ver; - ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver); + ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (thread ? "-mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver); } } if ( project->isActiveConfig( "activeqt" ) ) { @@ -619,13 +643,13 @@ DspMakefileGenerator::init() } if ( project->isActiveConfig("opengl") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; } - if ( project->isActiveConfig("thread") ) { + if ( thread ) { if(project->isActiveConfig("qt")) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT" ); if ( project->isActiveConfig("dll") || project->first("TARGET") == "qtmain" || !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { project->variables()["MSVCDSP_MTDEFD"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; project->variables()["MSVCDSP_MTDEF"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"]; @@ -729,12 +753,13 @@ DspMakefileGenerator::init() if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) project->variables()["MSVCDSP_LFLAGS" ].append(varGlue("QMAKE_LIBDIR","/LIBPATH:\"","\" /LIBPATH:\"","\"")); project->variables()["MSVCDSP_CXXFLAGS" ] += project->variables()["QMAKE_CXXFLAGS"]; project->variables()["MSVCDSP_DEFINES"].append(varGlue("DEFINES","/D ","" " /D ","")); project->variables()["MSVCDSP_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ","")); + processPrlFiles(); QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) { QString lib = (*libit); lib.replace(QRegExp("\""), ""); project->variables()["MSVCDSP_LIBS"].append(" \"" + lib + "\""); } @@ -751,12 +776,24 @@ DspMakefileGenerator::init() project->variables()["MSVCDSP_RELDEFS"].append("/D \"QT_NO_DEBUG\""); } else { project->variables()["MSVCDSP_RELDEFS"].clear(); } QString dest; + QString postLinkStep; + QString copyDllStep; + QString activeQtStepPreCopyDll; + QString activeQtStepPostCopyDll; + QString activeQtStepPreCopyDllDebug; + QString activeQtStepPostCopyDllDebug; + QString activeQtStepPreCopyDllRelease; + QString activeQtStepPostCopyDllRelease; + + if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) + postLinkStep += var("QMAKE_POST_LINK"); + if ( !project->variables()["DESTDIR"].isEmpty() ) { project->variables()["TARGET"].first().prepend(project->first("DESTDIR")); Option::fixPathToTargetOS(project->first("TARGET")); dest = project->first("TARGET"); if ( project->first("TARGET").startsWith("$(QTDIR)") ) dest.replace( "$(QTDIR)", getenv("QTDIR") ); @@ -767,73 +804,78 @@ DspMakefileGenerator::init() imp.replace(".dll", ".lib"); project->variables()["MSVCDSP_TARGET"].append(QString(" /implib:\"") + imp + "\""); } } if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; - QString copydll = "# Begin Special Build Tool\n" - "TargetPath=" + dest + "\n" - "SOURCE=$(InputPath)\n" - "PostBuild_Desc=Copy DLL to " + project->first("DLLDESTDIR") + "\n" - "PostBuild_Cmds="; - + if ( dlldirs.count() ) + copyDllStep += "\t"; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { - copydll += "copy \"" + dest + "\" \"" + *dlldir + "\"\t"; + copyDllStep += "copy \"$(TargetPath)\" \"" + *dlldir + "\"\t"; } - - copydll += "\n# End Special Build Tool"; - project->variables()["MSVCDSP_COPY_DLL_REL"].append( copydll ); - project->variables()["MSVCDSP_COPY_DLL_DBG"].append( copydll ); } + if ( project->isActiveConfig("activeqt") ) { QString idl = project->variables()["QMAKE_IDL"].first(); QString idc = project->variables()["QMAKE_IDC"].first(); QString version = project->variables()["VERSION"].first(); if ( version.isEmpty() ) version = "1.0"; project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".idl" ); project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".tlb" ); project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".midl" ); if ( project->isActiveConfig( "dll" ) ) { - QString regcmd = "# Begin Special Build Tool\n" - "TargetPath=" + targetfilename + "\n" - "SOURCE=$(InputPath)\n" - "PostBuild_Desc=Finalizing ActiveQt server...\n" - "PostBuild_Cmds=" + - idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version + + activeQtStepPreCopyDll += + "\t" + idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version + "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" - "\t" + idc + " %1 /regserver\n" - "# End Special Build Tool"; + "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"; + activeQtStepPostCopyDll += + "\t" + idc + " %1 /regserver\n"; - QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first(); - project->variables()["MSVCDSP_COPY_DLL_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) ); + QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + targetfilename + ".dll"; + activeQtStepPreCopyDllRelease = activeQtStepPreCopyDll.arg(executable).arg(executable); + activeQtStepPostCopyDllRelease = activeQtStepPostCopyDll.arg(executable); - executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first(); - project->variables()["MSVCDSP_COPY_DLL_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) ); + executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + targetfilename + ".dll"; + activeQtStepPreCopyDllDebug = activeQtStepPreCopyDll.arg(executable).arg(executable); + activeQtStepPostCopyDllDebug = activeQtStepPostCopyDll.arg(executable); } else { - QString regcmd = "# Begin Special Build Tool\n" - "TargetPath=" + targetfilename + "\n" - "SOURCE=$(InputPath)\n" - "PostBuild_Desc=Finalizing ActiveQt server...\n" - "PostBuild_Cmds=" - "%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version + + activeQtStepPreCopyDll += + "\t%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version + "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" - "\t%1 -regserver\n" - "# End Special Build Tool"; - - QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first(); - project->variables()["MSVCDSP_REGSVR_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) ); - - executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first(); - project->variables()["MSVCDSP_REGSVR_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) ); + "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"; + activeQtStepPostCopyDll += + "\t%1 -regserver\n"; + QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + targetfilename + ".exe"; + activeQtStepPreCopyDllRelease = activeQtStepPreCopyDll.arg(executable).arg(executable); + activeQtStepPostCopyDllRelease = activeQtStepPostCopyDll.arg(executable); + + executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + targetfilename + ".exe"; + activeQtStepPreCopyDllDebug = activeQtStepPreCopyDll.arg(executable).arg(executable); + activeQtStepPostCopyDllDebug = activeQtStepPostCopyDll.arg(executable); } } + + + if ( !postLinkStep.isEmpty() || !copyDllStep.isEmpty() || !activeQtStepPreCopyDllDebug.isEmpty() || !activeQtStepPreCopyDllRelease.isEmpty() ) { + project->variables()["MSVCDSP_POST_LINK_DBG"].append( + "# Begin Special Build Tool\n" + "SOURCE=$(InputPath)\n" + "PostBuild_Desc=Post Build Step\n" + "PostBuild_Cmds=" + postLinkStep + activeQtStepPreCopyDllDebug + copyDllStep + activeQtStepPostCopyDllDebug + "\n" + "# End Special Build Tool\n" ); + project->variables()["MSVCDSP_POST_LINK_REL"].append( + "# Begin Special Build Tool\n" + "SOURCE=$(InputPath)\n" + "PostBuild_Desc=Post Build Step\n" + "PostBuild_Cmds=" + postLinkStep + activeQtStepPreCopyDllRelease + copyDllStep + activeQtStepPostCopyDllRelease + "\n" + "# End Special Build Tool\n" ); + } + if ( !project->variables()["SOURCES"].isEmpty() || !project->variables()["RC_FILE"].isEmpty() ) { project->variables()["SOURCES"] += project->variables()["RC_FILE"]; } QStringList &list = project->variables()["FORMS"]; for( it = list.begin(); it != list.end(); ++it ) { if ( QFile::exists( *it + ".h" ) ) @@ -841,13 +883,13 @@ DspMakefileGenerator::init() } project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCDSP_LIBS"; } QString -DspMakefileGenerator::findTemplate(QString file) +DspMakefileGenerator::findTemplate(const QString &file) { QString ret; if(!QFile::exists((ret = file)) && !QFile::exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) && !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/win32-msvc/" + file)) && !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file)))) @@ -868,64 +910,65 @@ DspMakefileGenerator::processPrlVariable(const QString &var, const QStringList & } else { MakefileGenerator::processPrlVariable(var, l); } } -int +void DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, - QString filter) + const QString& filter) { if(project->isActiveConfig("flat")) - return 0; + return; fileFixify(file, QDir::currentDirPath(), QDir::currentDirPath(), TRUE); file = file.section(Option::dir_sep, 0, -2); if(file.right(Option::dir_sep.length()) != Option::dir_sep) file += Option::dir_sep; if(file == currentGroup) - return 0; + return; if(file.isEmpty() || !QDir::isRelativePath(file)) { endGroups(t); - return 0; + return; } if(file.startsWith(currentGroup)) file = file.mid(currentGroup.length()); - else - endGroups(t); - int lvl = file.contains(Option::dir_sep), old_lvl = currentGroup.contains(Option::dir_sep); - if(lvl > old_lvl) { - QStringList dirs = QStringList::split(Option::dir_sep, file); - for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { - t << "# Begin Group \"" << (*dir_it) << "\"\n" - << "# Prop Default_Filter \"" << filter << "\"\n"; - } - } else { - for(int x = old_lvl - lvl; x; x--) + int dirSep = currentGroup.findRev( Option::dir_sep ); + while( !file.startsWith( currentGroup ) && dirSep != -1 ) { + currentGroup.truncate( dirSep ); + dirSep = currentGroup.findRev( Option::dir_sep ); + if ( !file.startsWith( currentGroup ) && dirSep != -1 ) t << "\n# End Group\n"; } + if ( !file.startsWith( currentGroup ) ) { + t << "\n# End Group\n"; + currentGroup = ""; + } + QStringList dirs = QStringList::split(Option::dir_sep, file.right( file.length() - currentGroup.length() ) ); + for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { + t << "# Begin Group \"" << (*dir_it) << "\"\n" + << "# Prop Default_Filter \"" << filter << "\"\n"; + } currentGroup = file; - return lvl - old_lvl; } -int +void DspMakefileGenerator::endGroups(QTextStream &t) { if(project->isActiveConfig("flat")) - return 0; + return; else if(currentGroup.isEmpty()) - return 0; + return; QStringList dirs = QStringList::split(Option::dir_sep, currentGroup); for(QStringList::Iterator dir_it = dirs.end(); dir_it != dirs.begin(); --dir_it) { t << "\n# End Group\n"; } currentGroup = ""; - return dirs.count(); } bool DspMakefileGenerator::openOutput(QFile &file) const { QString outdir; diff --git a/qmake/generators/win32/msvc_dsp.h b/qmake/generators/win32/msvc_dsp.h index a7fc3e7..3a7d18e 100644 --- a/qmake/generators/win32/msvc_dsp.h +++ b/qmake/generators/win32/msvc_dsp.h @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -31,29 +31,29 @@ ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef __DSPMAKE_H__ -#define __DSPMAKE_H__ +#ifndef __MSVC_DSP_H__ +#define __MSVC_DSP_H__ #include "winmakefile.h" #include <qvaluestack.h> class DspMakefileGenerator : public Win32MakefileGenerator { QString currentGroup; - int beginGroupForFile(QString file, QTextStream &, const QString filter=""); - int endGroups(QTextStream &); + void beginGroupForFile(QString file, QTextStream &, const QString& filter=""); + void endGroups(QTextStream &); bool init_flag; bool writeDspParts(QTextStream &); bool writeMakefile(QTextStream &); - QString findTemplate(QString file); + QString findTemplate(const QString &file); void init(); public: DspMakefileGenerator(QMakeProject *p); ~DspMakefileGenerator(); @@ -67,7 +67,7 @@ protected: inline DspMakefileGenerator::~DspMakefileGenerator() { } inline bool DspMakefileGenerator::findLibraries() { return Win32MakefileGenerator::findLibraries("MSVCDSP_LIBS"); } -#endif /* __DSPMAKE_H__ */ +#endif /* __MSVC_DSP_H__ */ diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 9cc9a69..ecef34d 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -35,12 +35,13 @@ ** **********************************************************************/ #include "msvc_nmake.h" #include "option.h" #include <qregexp.h> +#include <qdict.h> #include <qdir.h> #include <stdlib.h> #include <time.h> NmakeMakefileGenerator::NmakeMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) @@ -132,12 +133,14 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) t << "ZIP = " << var("QMAKE_ZIP") << endl; t << "COPY_FILE = " << var("QMAKE_COPY") << endl; t << "COPY_DIR = " << var("QMAKE_COPY") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; + t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; t << endl; t << "####### Files" << endl << endl; t << "HEADERS = " << varList("HEADERS") << endl; t << "SOURCES = " << varList("SOURCES") << endl; t << "OBJECTS = " << varList("OBJECTS") << endl; @@ -153,29 +156,72 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) else t << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first(); t << endl; t << endl; t << "####### Implicit rules" << endl << endl; - t << ".SUFFIXES: .cpp .cxx .cc .c" << endl << endl; - t << ".cpp.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".cxx.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".cc.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".c.obj:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + t << ".SUFFIXES: .c"; + QStringList::Iterator cppit; + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << " " << (*cppit); + t << endl << endl; + if(!project->isActiveConfig("no_batch")) { + // Batchmode doesn't use the non implicit rules QMAKE_RUN_CXX & QMAKE_RUN_CC + project->variables().remove("QMAKE_RUN_CXX"); + project->variables().remove("QMAKE_RUN_CC"); + + QDict<void> source_directories; + source_directories.insert(".", (void*)1); + if(!project->isEmpty("MOC_DIR")) + source_directories.insert(project->first("MOC_DIR"), (void*)1); + if(!project->isEmpty("UI_SOURCES_DIR")) + source_directories.insert(project->first("UI_SOURCES_DIR"), (void*)1); + else if(!project->isEmpty("UI_DIR")) + source_directories.insert(project->first("UI_DIR"), (void*)1); + QString srcs[] = { QString("SOURCES"), QString("UICIMPLS"), QString("SRCMOC"), QString::null }; + for(int x = 0; !srcs[x].isNull(); x++) { + QStringList &l = project->variables()[srcs[x]]; + for(QStringList::Iterator sit = l.begin(); sit != l.end(); ++sit) { + QString sep = "\\"; + if((*sit).find(sep) == -1) + sep = "/"; + QString dir = (*sit).section(sep, 0, -2); + if(!dir.isEmpty() && !source_directories[dir]) + source_directories.insert(dir, (void*)1); + } + } + + for(QDictIterator<void> it(source_directories); it.current(); ++it) { + if(it.currentKey().isEmpty()) + continue; + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << "{" << it.currentKey() << "}" << (*cppit) << "{" << var("OBJECTS_DIR") << "}" << Option::obj_ext << "::\n\t" + << var("QMAKE_RUN_CXX_IMP_BATCH").replace( QRegExp( "\\$@" ), var("OBJECTS_DIR") ) << endl << "\t$<" << endl << "<<" << endl << endl; + t << "{" << it.currentKey() << "}" << ".c{" << var("OBJECTS_DIR") << "}" << Option::obj_ext << "::\n\t" + << var("QMAKE_RUN_CC_IMP_BATCH").replace( QRegExp( "\\$@" ), var("OBJECTS_DIR") ) << endl << "\t$<" << endl << "<<" << endl << endl; + } + } else { + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".c" << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + } t << "####### Build rules" << endl << endl; t << "all: " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; - t << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("TARGETDEPS"); + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << var("POST_TARGETDEPS"); if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { t << "\n\t" << "$(LINK) $(LFLAGS) /OUT:$(TARGET) @<< " << "\n\t " << "$(OBJECTS) $(OBJMOC) $(LIBS)"; } else { t << "\n\t" << "$(LIB) /OUT:$(TARGET) @<<" << "\n\t " << "$(OBJECTS) $(OBJMOC)"; } t << endl << "<<" << endl; + if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) + t << "\t" << var( "QMAKE_POST_LINK" ) << endl; if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { t << "\n\t" << "-copy $(TARGET) " << *dlldir; } } @@ -217,12 +263,13 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","") << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","") << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","") << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","") << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","") << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ",""); + if ( project->isActiveConfig("activeqt")) { t << ("\n\t-del tmp\\" + targetfilename + ".*"); t << "\n\t-del tmp\\dump.*"; } if(!project->isEmpty("IMAGES")) t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); @@ -243,12 +290,16 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) } t << "\n\n" << targ << ":" << deps << "\n\t" << cmd; } t << endl << endl; + + t << "distclean: clean" + << "\n\t-del $(TARGET)" + << endl << endl; } void NmakeMakefileGenerator::init() { @@ -428,12 +479,34 @@ NmakeMakefileGenerator::init() } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; } + if ( project->isActiveConfig("stl") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; + } + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + if ( project->isActiveConfig("moc") ) setMocAware(TRUE); project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); @@ -462,27 +535,28 @@ NmakeMakefileGenerator::init() fprintf(stderr, "Both .rc and .res file specified.\n"); fprintf(stderr, "Please specify one of them, not both."); exit(666); } project->variables()["RES_FILE"] = project->variables()["RC_FILE"]; project->variables()["RES_FILE"].first().replace(".rc",".res"); - project->variables()["TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; } if ( !project->variables()["RES_FILE"].isEmpty()) project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; MakefileGenerator::init(); if ( !project->variables()["VERSION"].isEmpty()) { QStringList l = QStringList::split('.', project->first("VERSION")); project->variables()["VER_MAJ"].append(l[0]); project->variables()["VER_MIN"].append(l[1]); } + + QString version = QStringList::split('.', project->first("VERSION")).join(""); if(project->isActiveConfig("dll")) { - project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".lib"); - project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".exp"); + project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".exp"); } if(project->isActiveConfig("debug")) { - project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".pdb"); - project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".ilk"); + project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".pdb"); + project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".ilk"); project->variables()["QMAKE_CLEAN"].append("vc*.pdb"); } } diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index d3e170f..579fc35 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -31,14 +31,14 @@ ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef __NMAKEMAKE_H__ -#define __NMAKEMAKE_H__ +#ifndef __MSVC_NMAKE_H__ +#define __MSVC_NMAKE_H__ #include "winmakefile.h" class NmakeMakefileGenerator : public Win32MakefileGenerator { bool init_flag; @@ -53,7 +53,7 @@ public: }; inline NmakeMakefileGenerator::~NmakeMakefileGenerator() { } -#endif /* __NMAKEMAKE_H__ */ +#endif /* __MSVC_NMAKE_H__ */ diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index c2b9e30..7ffe4f7 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -251,33 +251,33 @@ const char* _WarnLevel = "\n\t\t\t\tWarnLevel=\""; const char* _WarningLevel = "\n\t\t\t\tWarningLevel=\""; const char* _WholeProgramOptimization = "\n\t\t\t\tWholeProgramOptimization=\""; // Property name and value as Pairs --------------------------------- struct TPair { TPair( const char* n, const triState v ) : name(n), value(v) {}; - const char* name; - const triState value; + const char* name; + const triState value; }; -struct EPair { +struct EPair { EPair( const char* n, const int v ) : name(n), value(v) {}; - const char* name; + const char* name; const int value; }; -struct LPair { +struct LPair { LPair( const char* n, const long v ) : name(n), value(v) {}; - const char* name; - const long value; + const char* name; + const long value; }; -struct SPair { +struct SPair { SPair( const char* n, const QString& v ) : name(n), value(v) {}; - const char* name; - const QString& value; + const char* name; + const QString& value; }; -struct XPair { +struct XPair { XPair( const char* n, const QStringList& v, const char* s = "," ) : name(n), value(v), sep(s) {}; - const char* name; + const char* name; const QStringList& value; const char* sep; }; // void streamSPair( QTextStream &strm, const char *n, const QString &s ) @@ -380,13 +380,13 @@ VCCLCompilerTool::VCCLCompilerTool() QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) { strm << _begTool3; strm << _VCCLCompilerToolName; strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _AdditionalUsingDirectories, tool.AdditionalUsingDirectories ); strm << SPair( _AssemblerListingLocation, tool.AssemblerListingLocation ); if ( tool.AssemblerOutput != asmListingNone ) strm << EPair( _AssemblerOutput, tool.AssemblerOutput ); if ( tool.BasicRuntimeChecks != runtimeBasicCheckNone ) strm << EPair( _BasicRuntimeChecks, tool.BasicRuntimeChecks ); if ( tool.BrowseInformation != brInfoNone ) strm << EPair( _BrowseInformation, tool.BrowseInformation ); strm << SPair( _BrowseInformationFile, tool.BrowseInformationFile ); @@ -439,40 +439,44 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << XPair( _UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions ); if ( !tool.PrecompiledHeaderFile.isEmpty() || !tool.PrecompiledHeaderThrough.isEmpty() ) strm << EPair( _UsePrecompiledHeader, tool.UsePrecompiledHeader ); strm << TPair( _WarnAsError, tool.WarnAsError ); strm << EPair( _WarningLevel, tool.WarningLevel ); - strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization ); + strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization ); strm << "/>"; return strm; } bool VCCLCompilerTool::parseOption( const char* option ) { // skip index 0 ('/' or '-') - char first = option[1]; + char first = option[1]; char second = option[2]; char third = option[3]; char fourth = option[4]; + bool found = TRUE; switch ( first ) { case '?': case 'h': qWarning( "Generator: Option '/?', '/help': MSVC.NET projects do not support outputting help info" ); - return FALSE; + found = FALSE; + break; case '@': qWarning( "Generator: Option '/@': MSVC.NET projects do not support the use of a response file" ); - return FALSE; + found = FALSE; + break; case 'l': qWarning( "Generator: Option '/link': qmake generator does not support passing link options through the compiler tool" ); - return FALSE; - + found = FALSE; + break; case 'A': - if ( second != 'I' ) - return FALSE; + if ( second != 'I' ) { + found = FALSE; break; + } AdditionalUsingDirectories += option+2; break; case 'C': KeepComments = _True; break; case 'D': @@ -484,13 +488,13 @@ bool VCCLCompilerTool::parseOption( const char* option ) // ExceptionHandling must be false, or it will override // with an /EHsc option ExceptionHandling = _False; AdditionalOptions += option; break; } - return FALSE; + found = FALSE; break; } GeneratePreprocessedFile = preprocessYes; break; case 'F': if ( second <= '9' && second >= '0' ) { AdditionalOptions += option; @@ -541,22 +545,22 @@ bool VCCLCompilerTool::parseOption( const char* option ) PrecompiledHeaderFile = option+3; break; case 'x': ExpandAttributedSource = _True; break; default: - return FALSE; + found = FALSE; break; } } break; case 'G': switch ( second ) { case '3': case '4': qWarning( "Option '/G3' and '/G4' were phased out in Visual C++ 5.0" ); - return FALSE; + found = FALSE; break; case '5': OptimizeForProcessor = procOptimizePentium; break; case '6': case 'B': OptimizeForProcessor = procOptimizePentiumProAndAbove; @@ -616,13 +620,13 @@ bool VCCLCompilerTool::parseOption( const char* option ) EnableFunctionLevelLinking = _True; break; case 'z': CallingConvention = callConventionStdCall; break; default: - return FALSE; + found = FALSE; break; } break; case 'H': AdditionalOptions += option; break; case 'I': @@ -630,13 +634,13 @@ bool VCCLCompilerTool::parseOption( const char* option ) break; case 'L': if ( second == 'D' ) { AdditionalOptions += option; break; } - return FALSE; + found = FALSE; break; case 'M': if ( second == 'D' ) { RuntimeLibrary = rtMultiThreadedDLL; if ( third == 'd' ) RuntimeLibrary = rtMultiThreadedDebugDLL; break; @@ -648,13 +652,13 @@ bool VCCLCompilerTool::parseOption( const char* option ) } else if ( second == 'T' ) { RuntimeLibrary = rtMultiThreaded; if ( third == 'd' ) RuntimeLibrary = rtMultiThreadedDebug; break; } - return FALSE; + found = FALSE; break; case 'O': switch ( second ) { case '1': Optimization = optimizeMinSpace; break; case '2': @@ -668,13 +672,13 @@ bool VCCLCompilerTool::parseOption( const char* option ) InlineFunctionExpansion = expandDisable; else if ( third == '1' ) InlineFunctionExpansion = expandOnlyInline; else if ( third == '2' ) InlineFunctionExpansion = expandAnySuitable; else - return FALSE; + found = FALSE; break; case 'd': Optimization = optimizeDisabled; break; case 'g': GlobalOptimizations = _True; @@ -702,46 +706,46 @@ bool VCCLCompilerTool::parseOption( const char* option ) case 'y': OmitFramePointers = _True; if ( third == '-' ) OmitFramePointers = _False; break; default: - return FALSE; + found = FALSE; break; } break; case 'P': GeneratePreprocessedFile = preprocessYes; break; case 'Q': if ( second == 'I' ) { AdditionalOptions += option; break; } - return FALSE; + found = FALSE; break; case 'R': if ( second == 'T' && third == 'C' ) { if ( fourth == '1' ) BasicRuntimeChecks = runtimeBasicCheckAll; else if ( fourth == 'c' ) SmallerTypeCheck = _True; else if ( fourth == 's' ) BasicRuntimeChecks = runtimeCheckStackFrame; else if ( fourth == 'u' ) BasicRuntimeChecks = runtimeCheckUninitVariables; else - return FALSE; + found = FALSE; break; } break; case 'T': if ( second == 'C' ) { CompileAs = compileAsC; } else if ( second == 'P' ) { CompileAs = compileAsCPlusPlus; } else { qWarning( "Generator: Options '/Tp<filename>' and '/Tc<filename>' are not supported by qmake" ); - return FALSE; + found = FALSE; break; } break; case 'U': UndefinePreprocessorDefinitions += option+2; break; case 'V': @@ -775,13 +779,13 @@ bool VCCLCompilerTool::parseOption( const char* option ) if ( third == '6' && fourth == '4' ) { Detect64BitPortabilityProblems = _True; break; } // Fallthrough default: - return FALSE; + found = FALSE; break; } break; case 'X': IgnoreStandardIncludePath = _True; break; case 'Y': @@ -804,13 +808,13 @@ bool VCCLCompilerTool::parseOption( const char* option ) break; case 'u': UsePrecompiledHeader = pchUseUsingSpecific; PrecompiledHeaderFile = option+3; break; default: - return FALSE; + found = FALSE; break; } break; case 'Z': switch ( second ) { case '7': DebugInformationFormat = debugOldStyleInfo; @@ -837,15 +841,15 @@ bool VCCLCompilerTool::parseOption( const char* option ) if ( third == ':' ) { if ( fourth == 'f' ) ForceConformanceInForLoopScope = _True; else if ( fourth == 'w' ) TreatWChar_tAsBuiltInType = _True; else - return FALSE; + found = FALSE; } else { - return FALSE; + found = FALSE; break; } break; case 'g': case 'm': case 's': AdditionalOptions += option; @@ -866,17 +870,17 @@ bool VCCLCompilerTool::parseOption( const char* option ) StructMemberAlignment = alignFourBytes; break; case '8': StructMemberAlignment = alignEightBytes; break; default: - return FALSE; + found = FALSE; break; } break; default: - return FALSE; + found = FALSE; break; } break; case 'c': if ( second == '\0' ) { CompileOnly = _True; } else if ( second == 'l' ) { @@ -884,45 +888,46 @@ bool VCCLCompilerTool::parseOption( const char* option ) CompileAsManaged = managedAssembly; TurnOffAssemblyGeneration = _True; } else { CompileAsManaged = managedAssembly; } } else { - return FALSE; + found = FALSE; break; } break; case 'd': - if ( second != 'r' ) - return FALSE; + if ( second != 'r' ) { + found = FALSE; break; + } CompileAsManaged = managedAssembly; break; case 'n': if ( second == 'o' && third == 'B' && fourth == 'o' ) { AdditionalOptions += "/noBool"; break; } if ( second == 'o' && third == 'l' && fourth == 'o' ) { SuppressStartupBanner = _True; break; } - return FALSE; + found = FALSE; break; case 's': if ( second == 'h' && third == 'o' && fourth == 'w' ) { ShowIncludes = _True; break; } - return FALSE; + found = FALSE; break; case 'u': UndefineAllPreprocessorDefinitions = _True; break; case 'v': if ( second == 'd' || second == 'm' ) { AdditionalOptions += option; break; } - return FALSE; + found = FALSE; break; case 'w': switch ( second ) { case '\0': WarningLevel = warningLevel_0; break; case 'd': @@ -930,14 +935,16 @@ bool VCCLCompilerTool::parseOption( const char* option ) break; default: AdditionalOptions += option; } break; default: - return FALSE; + found = FALSE; break; } + if( !found ) + warn_msg( WarnLogic, "Could not parse Compiler option: %s", option ); return TRUE; } // VCLinkerTool ----------------------------------------------------- VCLinkerTool::VCLinkerTool() : EnableCOMDATFolding( optFoldingDefault ), @@ -977,13 +984,13 @@ VCLinkerTool::VCLinkerTool() QTextStream &operator<<( QTextStream &strm, const VCLinkerTool &tool ) { strm << _begTool3; strm << _VCLinkerToolName; strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies, " " ); strm << XPair( _AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _AddModuleNamesToAssembly, tool.AddModuleNamesToAssembly ); strm << SPair( _BaseAddress, tool.BaseAddress ); strm << XPair( _DelayLoadDLLs, tool.DelayLoadDLLs ); if ( tool.EnableCOMDATFolding != optFoldingDefault ) strm << EPair( _EnableCOMDATFolding, tool.EnableCOMDATFolding ); strm << SPair( _EntryPointSymbol, tool.EntryPointSymbol ); strm << XPair( _ForceSymbolReferences, tool.ForceSymbolReferences ); @@ -1043,65 +1050,69 @@ static uint elfHash( const char* name ) const uchar *k; uint h = 0; uint g; if ( name ) { k = (const uchar *) name; - while ( (*k) && - (*k)!= ':' && + while ( (*k) && + (*k)!= ':' && (*k)!=',' && (*k)!=' ' ) { h = ( h << 4 ) + *k++; if ( (g = (h & 0xf0000000)) != 0 ) h ^= g >> 24; h &= ~g; } } if ( !h ) h = 1; return h; } + +//#define USE_DISPLAY_HASH +#ifdef USE_DISPLAY_HASH static void displayHash( const char* str ) { printf( "case 0x%07x: // %s\n break;\n", elfHash(str), str ); } +#endif bool VCLinkerTool::parseOption( const char* option ) { -#if 0 +#ifdef USE_DISPLAY_HASH // Main options - displayHash( "/ALIGN" ); displayHash( "/ALLOWBIND" ); displayHash( "/ASSEMBLYMODULE" ); - displayHash( "/ASSEMBLYRESOURCE" ); displayHash( "/BASE" ); displayHash( "/DEBUG" ); - displayHash( "/DEF" ); displayHash( "/DEFAULTLIB" ); displayHash( "/DELAY" ); - displayHash( "/DELAYLOAD" ); displayHash( "/DLL" ); displayHash( "/DRIVER" ); - displayHash( "/ENTRY" ); displayHash( "/EXETYPE" ); displayHash( "/EXPORT" ); - displayHash( "/FIXED" ); displayHash( "/FORCE" ); displayHash( "/HEAP" ); - displayHash( "/IDLOUT" ); displayHash( "/IGNOREIDL" ); displayHash( "/IMPLIB" ); - displayHash( "/INCLUDE" ); displayHash( "/INCREMENTAL" ); displayHash( "/LARGEADDRESSAWARE" ); - displayHash( "/LIBPATH" ); displayHash( "/LTCG" ); displayHash( "/MACHINE" ); - displayHash( "/MAP" ); displayHash( "/MAPINFO" ); displayHash( "/MERGE" ); - displayHash( "/MIDL" ); displayHash( "/NOASSEMBLY" ); displayHash( "/NODEFAULTLIB" ); - displayHash( "/NOENTRY" ); displayHash( "/NOLOGO" ); displayHash( "/OPT" ); - displayHash( "/ORDER" ); displayHash( "/OUT" ); displayHash( "/PDB" ); - displayHash( "/PDBSTRIPPED" ); displayHash( "/RELEASE" ); displayHash( "/SECTION" ); - displayHash( "/STACK" ); displayHash( "/STUB" ); displayHash( "/SUBSYSTEM" ); - displayHash( "/SWAPRUN" ); displayHash( "/TLBID" ); displayHash( "/TLBOUT" ); - displayHash( "/TSAWARE" ); displayHash( "/VERBOSE" ); displayHash( "/VERSION" ); + displayHash( "/ALIGN" ); displayHash( "/ALLOWBIND" ); displayHash( "/ASSEMBLYMODULE" ); + displayHash( "/ASSEMBLYRESOURCE" ); displayHash( "/BASE" ); displayHash( "/DEBUG" ); + displayHash( "/DEF" ); displayHash( "/DEFAULTLIB" ); displayHash( "/DELAY" ); + displayHash( "/DELAYLOAD" ); displayHash( "/DLL" ); displayHash( "/DRIVER" ); + displayHash( "/ENTRY" ); displayHash( "/EXETYPE" ); displayHash( "/EXPORT" ); + displayHash( "/FIXED" ); displayHash( "/FORCE" ); displayHash( "/HEAP" ); + displayHash( "/IDLOUT" ); displayHash( "/IGNOREIDL" ); displayHash( "/IMPLIB" ); + displayHash( "/INCLUDE" ); displayHash( "/INCREMENTAL" ); displayHash( "/LARGEADDRESSAWARE" ); + displayHash( "/LIBPATH" ); displayHash( "/LTCG" ); displayHash( "/MACHINE" ); + displayHash( "/MAP" ); displayHash( "/MAPINFO" ); displayHash( "/MERGE" ); + displayHash( "/MIDL" ); displayHash( "/NOASSEMBLY" ); displayHash( "/NODEFAULTLIB" ); + displayHash( "/NOENTRY" ); displayHash( "/NOLOGO" ); displayHash( "/OPT" ); + displayHash( "/ORDER" ); displayHash( "/OUT" ); displayHash( "/PDB" ); + displayHash( "/PDBSTRIPPED" ); displayHash( "/RELEASE" ); displayHash( "/SECTION" ); + displayHash( "/STACK" ); displayHash( "/STUB" ); displayHash( "/SUBSYSTEM" ); + displayHash( "/SWAPRUN" ); displayHash( "/TLBID" ); displayHash( "/TLBOUT" ); + displayHash( "/TSAWARE" ); displayHash( "/VERBOSE" ); displayHash( "/VERSION" ); displayHash( "/VXD" ); displayHash( "/WS " ); #endif -#if 0 +#ifdef USE_DISPLAY_HASH // Sub options displayHash( "UNLOAD" ); displayHash( "NOBIND" ); displayHash( "no" ); displayHash( "NOSTATUS" ); displayHash( "STATUS" ); - displayHash( "AM33" ); displayHash( "ARM" ); displayHash( "CEE" ); displayHash( "IA64" ); displayHash( "X86" ); displayHash( "M32R" ); - displayHash( "MIPS" ); displayHash( "MIPS16" ); displayHash( "MIPSFPU" ); displayHash( "MIPSFPU16" ); displayHash( "MIPSR41XX" ); displayHash( "PPC" ); - displayHash( "SH3" ); displayHash( "SH4" ); displayHash( "SH5" ); displayHash( "THUMB" ); displayHash( "TRICORE" ); displayHash( "EXPORTS" ); - displayHash( "LINES" ); displayHash( "REF" ); displayHash( "NOREF" ); displayHash( "ICF" ); displayHash( "WIN98" ); displayHash( "NOWIN98" ); - displayHash( "CONSOLE" ); displayHash( "EFI_APPLICATION" ); displayHash( "EFI_BOOT_SERVICE_DRIVER" ); displayHash( "EFI_ROM" ); displayHash( "EFI_RUNTIME_DRIVER" ); displayHash( "NATIVE" ); - displayHash( "POSIX" ); displayHash( "WINDOWS" ); displayHash( "WINDOWSCE" ); displayHash( "NET" ); displayHash( "CD" ); displayHash( "NO" ); + displayHash( "AM33" ); displayHash( "ARM" ); displayHash( "CEE" ); displayHash( "IA64" ); displayHash( "X86" ); displayHash( "M32R" ); + displayHash( "MIPS" ); displayHash( "MIPS16" ); displayHash( "MIPSFPU" ); displayHash( "MIPSFPU16" ); displayHash( "MIPSR41XX" ); displayHash( "PPC" ); + displayHash( "SH3" ); displayHash( "SH4" ); displayHash( "SH5" ); displayHash( "THUMB" ); displayHash( "TRICORE" ); displayHash( "EXPORTS" ); + displayHash( "LINES" ); displayHash( "REF" ); displayHash( "NOREF" ); displayHash( "ICF" ); displayHash( "WIN98" ); displayHash( "NOWIN98" ); + displayHash( "CONSOLE" ); displayHash( "EFI_APPLICATION" ); displayHash( "EFI_BOOT_SERVICE_DRIVER" ); displayHash( "EFI_ROM" ); displayHash( "EFI_RUNTIME_DRIVER" ); displayHash( "NATIVE" ); + displayHash( "POSIX" ); displayHash( "WINDOWS" ); displayHash( "WINDOWSCE" ); displayHash( "NET" ); displayHash( "CD" ); displayHash( "NO" ); #endif - + bool found = TRUE; switch ( elfHash(option) ) { case 0x3360dbe: // /ALIGN[:number] case 0x1485c34: // /ALLOWBIND[:NO] case 0x6b21972: // /DEFAULTLIB:library case 0x396ea92: // /DRIVER[:UPONLY | :WDM] case 0xaca9d75: // /EXETYPE[:DYNAMIC | :DEV386] @@ -1138,13 +1149,13 @@ bool VCLinkerTool::parseOption( const char* option ) AdditionalOptions += option; break; case 0x06f4bf4: // /DELAYLOAD:dllname DelayLoadDLLs += option+11; break; // case 0x003390c: // /DLL - // This option is not used for vcproj files + // This option is not used for vcproj files // break; case 0x33a3979: // /ENTRY:function EntryPointSymbol = option+7; break; case 0x033c960: // /HEAP:reserve[,commit] { @@ -1189,13 +1200,13 @@ bool VCLinkerTool::parseOption( const char* option ) if ( *(option+5) == ':' && *(option+6) == 'S' ) ShowProgress = linkProgressAll; break; case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE} switch ( elfHash(option+9) ) { - // Very limited documentation on all options but X86, + // Very limited documentation on all options but X86, // so we put the others in AdditionalOptions... case 0x0046063: // AM33 case 0x000466d: // ARM case 0x0004795: // CEE case 0x004d494: // IA64 case 0x0050672: // M32R @@ -1213,13 +1224,13 @@ bool VCLinkerTool::parseOption( const char* option ) AdditionalOptions += option; break; case 0x0005bb6: // X86 TargetMachine = machineX86; break; default: - return FALSE; + found = FALSE; } break; case 0x0034160: // /MAP[:filename] GenerateMapFile = _True; MapFileName = option+5; break; @@ -1272,13 +1283,13 @@ bool VCLinkerTool::parseOption( const char* option ) OptimizeForWindows98 = optWin98Yes; break; case 'W': // NOWIN98 OptimizeForWindows98 = optWin98No; break; default: - return FALSE; + found = FALSE; } } break; case 0x34468a2: // /ORDER:@filename FunctionOrder = option+8; break; @@ -1321,23 +1332,23 @@ bool VCLinkerTool::parseOption( const char* option ) case 0x5268ea5: // NATIVE case 0x05547e8: // POSIX case 0x2949c95: // WINDOWSCE AdditionalOptions += option; break; default: - return FALSE; + found = FALSE; } } break; case 0x8b654de: // /SWAPRUN:{NET | CD} if ( *(option+9) == 'N' ) SwapRunFromNet = _True; else if ( *(option+9) == 'C' ) SwapRunFromCD = _True; else - return FALSE; + found = FALSE; break; case 0x34906d4: // /TLBID:id TypeLibraryResourceID = QString( option+7 ).toLong(); break; case 0x4907494: // /TLBOUT:[path\]filename TypeLibraryFile = option+8; @@ -1357,15 +1368,17 @@ bool VCLinkerTool::parseOption( const char* option ) } break; case 0xaa77f7e: // /VERSION:major[.minor] Version = option+9; break; default: - return FALSE; + found = FALSE; } - return TRUE; + if( !found ) + warn_msg( WarnLogic, "Could not parse Linker options: %s", option ); + return found; } // VCMIDLTool ------------------------------------------------------- VCMIDLTool::VCMIDLTool() : DefaultCharType( midlCharUnsigned ), EnableErrorChecks( midlDisableAll ), @@ -1389,13 +1402,13 @@ VCMIDLTool::VCMIDLTool() QTextStream &operator<<( QTextStream &strm, const VCMIDLTool &tool ) { strm << _begTool3; strm << _VCMIDLToolName; strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _CPreprocessOptions, tool.CPreprocessOptions ); strm << EPair( _DefaultCharType, tool.DefaultCharType ); strm << SPair( _DLLDataFileName, tool.DLLDataFileName ); strm << EPair( _EnableErrorChecks, tool.EnableErrorChecks ); strm << TPair( _ErrorCheckAllocations, tool.ErrorCheckAllocations ); strm << TPair( _ErrorCheckBounds, tool.ErrorCheckBounds ); @@ -1424,40 +1437,41 @@ QTextStream &operator<<( QTextStream &strm, const VCMIDLTool &tool ) strm << "/>"; return strm; } bool VCMIDLTool::parseOption( const char* option ) { -#if 0 +#ifdef USE_DISPLAY_HASH displayHash( "/D name[=def]" ); displayHash( "/I directory-list" ); displayHash( "/Oi" ); displayHash( "/Oic" ); displayHash( "/Oicf" ); displayHash( "/Oif" ); displayHash( "/Os" ); displayHash( "/U name" ); displayHash( "/WX" ); displayHash( "/W{0|1|2|3|4}" ); displayHash( "/Zp {N}" ); displayHash( "/Zs" ); displayHash( "/acf filename" ); displayHash( "/align {N}" ); displayHash( "/app_config" ); displayHash( "/c_ext" ); displayHash( "/char ascii7" ); displayHash( "/char signed" ); displayHash( "/char unsigned" ); displayHash( "/client none" ); displayHash( "/client stub" ); displayHash( "/confirm" ); - displayHash( "/cpp_cmd cmd_line" ); displayHash( "/cpp_opt options" ); + displayHash( "/cpp_cmd cmd_line" ); displayHash( "/cpp_opt options" ); displayHash( "/cstub filename" ); displayHash( "/dlldata filename" ); displayHash( "/env win32" ); displayHash( "/env win64" ); displayHash( "/error all" ); displayHash( "/error allocation" ); displayHash( "/error bounds_check" ); displayHash( "/error enum" ); displayHash( "/error none" ); displayHash( "/error ref" ); displayHash( "/error stub_data" ); displayHash( "/h filename" ); displayHash( "/header filename" ); displayHash( "/iid filename" ); displayHash( "/lcid" ); displayHash( "/mktyplib203" ); displayHash( "/ms_ext" ); displayHash( "/ms_union" ); displayHash( "/msc_ver <nnnn>" ); displayHash( "/newtlb" ); displayHash( "/no_cpp" ); displayHash( "/no_def_idir" ); displayHash( "/no_default_epv" ); displayHash( "/no_format_opt" ); displayHash( "/no_warn" ); displayHash( "/nocpp" ); displayHash( "/nologo" ); displayHash( "/notlb" ); - displayHash( "/o filename" ); displayHash( "/oldnames" ); displayHash( "/oldtlb" ); + displayHash( "/o filename" ); displayHash( "/oldnames" ); displayHash( "/oldtlb" ); displayHash( "/osf" ); displayHash( "/out directory" ); displayHash( "/pack {N}" ); displayHash( "/prefix all" ); displayHash( "/prefix client" ); displayHash( "/prefix server" ); displayHash( "/prefix switch" ); displayHash( "/protocol all" ); displayHash( "/protocol dce" ); displayHash( "/protocol ndr64" ); displayHash( "/proxy filename" ); displayHash( "/robust" ); displayHash( "/rpcss" ); displayHash( "/savePP" ); displayHash( "/server none" ); displayHash( "/server stub" ); displayHash( "/sstub filename" ); displayHash( "/syntax_check" ); displayHash( "/target {system}" ); displayHash( "/tlb filename" ); displayHash( "/use_epv" ); displayHash( "/win32" ); displayHash( "/win64" ); #endif + bool found = TRUE; int offset = 0; switch( elfHash(option) ) { case 0x0000334: // /D name[=def] PreprocessorDefinitions += option+3; break; case 0x0000339: // /I directory-list @@ -1487,13 +1501,13 @@ bool VCMIDLTool::parseOption( const char* option ) StructMemberAlignment = midlAlignFourBytes; break; case '8': StructMemberAlignment = midlAlignEightBytes; break; default: - return FALSE; + found = FALSE; } break; case 0x0359e82: // /char {ascii7|signed|unsigned} switch( *(option+6) ) { case 'a': DefaultCharType = midlCharAscii7; @@ -1502,13 +1516,13 @@ bool VCMIDLTool::parseOption( const char* option ) DefaultCharType = midlCharSigned; break; case 'u': DefaultCharType = midlCharUnsigned; break; default: - return FALSE; + found = FALSE; } break; case 0xa766524: // /cpp_opt options CPreprocessOptions += option+9; break; case 0xb32abf1: // /dlldata filename @@ -1533,19 +1547,19 @@ bool VCMIDLTool::parseOption( const char* option ) ErrorCheckEnumRange = _True; break; case 'n': EnableErrorChecks = midlDisableAll; break; case 'r': - break; ErrorCheckRefPointers = _True; - case 's': break; + case 's': ErrorCheckStubData = _True; + break; default: - return FALSE; + found = FALSE; } break; case 0x5eb7af2: // /header filename offset = 5; case 0x0000358: // /h filename HeaderFileName = option + offset + 3; @@ -1644,17 +1658,19 @@ bool VCMIDLTool::parseOption( const char* option ) WarningLevel = midlWarningLevel_3; break; case '4': WarningLevel = midlWarningLevel_4; break; default: - return FALSE; + found = FALSE; } } break; } + if( !found ) + warn_msg( WarnLogic, "Could not parse MIDL option: %s", option ); return TRUE; } // VCLibrarianTool -------------------------------------------------- VCLibrarianTool::VCLibrarianTool() : IgnoreAllDefaultLibraries( unset ), @@ -1665,13 +1681,13 @@ VCLibrarianTool::VCLibrarianTool() QTextStream &operator<<( QTextStream &strm, const VCLibrarianTool &tool ) { strm << _begTool3; strm << SPair( _ToolName, QString( "VCLibrarianTool" ) ); strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies ); strm << XPair( _AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _ExportNamedFunctions, tool.ExportNamedFunctions ); strm << XPair( _ForceSymbolReferences, tool.ForceSymbolReferences ); strm << TPair( _IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries ); strm << XPair( _IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames ); strm << SPair( _ModuleDefinitionFile, tool.ModuleDefinitionFile ); strm << SPair( _OutputFile, tool.OutputFile ); @@ -1711,13 +1727,13 @@ VCResourceCompilerTool::VCResourceCompilerTool() QTextStream &operator<<( QTextStream &strm, const VCResourceCompilerTool &tool ) { strm << _begTool3; strm << _VCResourceCompilerToolName; strm << SPair( _ToolPath, tool.ToolPath ); strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); if ( tool.Culture != rcUseDefault ) strm << EPair( _Culture, tool.Culture ); strm << XPair( _FullIncludePath, tool.FullIncludePath ); strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath ); strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions ); strm << SPair( _ResourceOutputFileName, tool.ResourceOutputFileName ); if ( tool.ShowProgress != linkProgressNotSet ) strm << EPair( _ShowProgress, tool.ShowProgress ); @@ -1848,35 +1864,56 @@ void VCFilter::generateMOC( QTextStream &strm, QString str ) const void VCFilter::generateUIC( QTextStream &strm, const QString& str ) const { QString uicApp = Project->var("QMAKE_UIC"); QString mocApp = Project->var( "QMAKE_MOC" ); QString fname = str.section( '\\', -1 ); QString mocDir = Project->var( "MOC_DIR" ); + QString uiDir = Project->var( "UI_DIR" ); + QString uiHeaders; + QString uiSources; + + // Determining the paths for the output files. + int slash = str.findRev( '\\' ); + QString pname = ( slash != -1 ) ? str.left( slash+1 ) : QString( ".\\" ); + if( !uiDir.isEmpty() ) { + uiHeaders = uiDir; + uiSources = uiDir; + } else { + uiHeaders = Project->var( "UI_HEADERS_DIR" ); + uiSources = Project->var( "UI_SOURCES_DIR" ); + if( uiHeaders.isEmpty() ) + uiHeaders = pname; + if( uiSources.isEmpty() ) + uiSources = pname; + } + if( !uiHeaders.endsWith( "\\" ) ) + uiHeaders += "\\"; + if( !uiSources.endsWith( "\\" ) ) + uiSources += "\\"; + + // Determine the file name. int dot = fname.findRev( '.' ); - if( dot != -1 ) + if( dot != -1 ) fname.truncate( dot ); - int slash = str.findRev( '\\' ); - QString pname = ( slash != -1 ) ? str.left( slash+1 ) : QString(".\\"); - strm << _begFileConfiguration; strm << _Name5; strm << Config->Name; strm << "\">"; strm << _begTool5; strm << _VCCustomBuildTool; strm << _Description6; strm << "Uic'ing " << str << "...\""; strm << _CommandLine6; - strm << uicApp << " " << str << " -o " << pname << fname << ".h && "; // Create .h from .ui file - strm << uicApp << " " << str << " -i " << fname << ".h -o " << pname << fname << ".cpp && "; // Create .cpp from .ui file - strm << mocApp << " " << pname << fname << ".h -o " << mocDir << "moc_" << fname << ".cpp\""; + strm << uicApp << " " << str << " -o " << uiHeaders << fname << ".h && "; // Create .h from .ui file + strm << uicApp << " " << str << " -i " << fname << ".h -o " << uiSources << fname << ".cpp && "; // Create .cpp from .ui file + strm << mocApp << " " << uiHeaders << fname << ".h -o " << mocDir << "moc_" << fname << ".cpp\""; strm << _AdditionalDependencies6; strm << mocApp << ";" << uicApp << "\""; strm << _Outputs6; - strm << pname << fname << ".h;" << pname << fname << ".cpp;" << mocDir << "moc_" << fname << ".cpp\""; + strm << uiHeaders << fname << ".h;" << uiSources << fname << ".cpp;" << mocDir << "moc_" << fname << ".cpp\""; strm << "/>"; strm << _endFileConfiguration; } QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) { @@ -1903,15 +1940,15 @@ QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) return strm; } // VCProject -------------------------------------------------------- VCProject::VCProject() { - QUuid uniqueId; #if defined(Q_WS_WIN32) GUID guid; + QUuid uniqueId; HRESULT h = CoCreateGuid( &guid ); if ( h == S_OK ) uniqueId = QUuid( guid ); ProjectGUID = uniqueId.toString(); #else // Qt doesn't support GUID on other platforms yet diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 2d09280..1dca68d 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -37,22 +37,22 @@ #include "project.h" #include <qstring.h> #include <qstringlist.h> /* - This Object model is of course VERY simplyfied, + This Object model is of course VERY simplyfied, and does not actually follow the original MSVC object model. However, it fulfilles the basic needs for qmake */ /* - If a triState value is 'unset' then the + If a triState value is 'unset' then the corresponding property is not in the output, - forcing the tool to utilize default values. + forcing the tool to utilize default values. False/True values will be in the output... */ enum customBuildCheck { none, moc, uic, @@ -80,13 +80,13 @@ enum basicRuntimeCheckOption { runtimeCheckStackFrame, runtimeCheckUninitVariables, runtimeBasicCheckAll }; enum browseInfoOption { brInfoNone, - brAllInfo, + brAllInfo, brNoLocalSymbols }; enum callingConventionOption { callConventionDefault = -1, callConventionCDecl, callConventionFastCall, @@ -115,19 +115,19 @@ enum ConfigurationTypes { }; enum debugOption { debugDisabled, debugOldStyleInfo, debugLineInfoOnly, debugEnabled, - debugEditAndContinue + debugEditAndContinue }; enum eAppProtectionOption { eAppProtectUnchanged, eAppProtectLow, eAppProtectMedium, - eAppProtectHigh + eAppProtectHigh }; enum enumResourceLangID { rcUseDefault = 0, rcAfrikaans = 1078, rcAlbanian = 1052, rcArabicAlgeria = 5121, @@ -228,13 +228,13 @@ enum enumSccEvent { eProjectInScc, ePreDirtyNotification }; enum favorSizeOrSpeedOption { favorNone, favorSpeed, - favorSize + favorSize }; enum genProxyLanguage { genProxyNative, genProxyManaged }; enum inlineExpansionOption { @@ -242,18 +242,18 @@ enum inlineExpansionOption { expandOnlyInline, expandAnySuitable }; enum linkIncrementalType { linkIncrementalDefault, linkIncrementalNo, - linkIncrementalYes + linkIncrementalYes }; enum linkProgressOption { linkProgressNotSet, linkProgressAll, - linkProgressLibs + linkProgressLibs }; enum machineTypeOption { machineNotSet, machineX86 }; enum midlCharOption { @@ -261,13 +261,13 @@ enum midlCharOption { midlCharSigned, midlCharAscii7 }; enum midlErrorCheckOption { midlEnableCustom, midlDisableAll, - midlEnableAll + midlEnableAll }; enum midlStructMemberAlignOption { midlAlignNotSet, midlAlignSingleByte, midlAlignTwoBytes, midlAlignFourBytes, @@ -281,25 +281,25 @@ enum midlTargetEnvironment { }; enum midlWarningLevelOption { midlWarningLevel_0, midlWarningLevel_1, midlWarningLevel_2, midlWarningLevel_3, - midlWarningLevel_4 + midlWarningLevel_4 }; enum optFoldingType { optFoldingDefault, optNoFolding, optFolding }; enum optimizeOption { optimizeDisabled, optimizeMinSpace, optimizeMaxSpeed, optimizeFull, - optimizeCustom + optimizeCustom }; enum optRefType { optReferencesDefault, optNoReferences, optReferences }; @@ -309,44 +309,44 @@ enum optWin98Type { optWin98Yes }; enum pchOption { pchNone, pchCreateUsingSpecific, pchGenerateAuto, - pchUseUsingSpecific + pchUseUsingSpecific }; enum preprocessOption { preprocessNo, preprocessYes, - preprocessNoLineNumbers + preprocessNoLineNumbers }; enum ProcessorOptimizeOption { procOptimizeBlended, procOptimizePentium, - procOptimizePentiumProAndAbove + procOptimizePentiumProAndAbove }; enum RemoteDebuggerType { DbgLocal, DbgRemote, - DbgRemoteTCPIP + DbgRemoteTCPIP }; enum runtimeLibraryOption { rtMultiThreaded, rtMultiThreadedDebug, rtMultiThreadedDLL, rtMultiThreadedDebugDLL, rtSingleThreaded, - rtSingleThreadedDebug + rtSingleThreadedDebug }; enum structMemberAlignOption { alignNotSet, alignSingleByte, alignTwoBytes, alignFourBytes, alignEightBytes, - alignSixteenBytes + alignSixteenBytes }; enum subSystemOption { subSystemNotSet, subSystemConsole, subSystemWindows }; @@ -363,23 +363,23 @@ enum toolSetType { toolSetAll }; enum TypeOfDebugger { DbgNativeOnly, DbgManagedOnly, DbgMixed, - DbgAuto + DbgAuto }; enum useOfATL { useATLNotSet, useATLStatic, - useATLDynamic + useATLDynamic }; enum useOfMfc { useMfcStdWin, useMfcStatic, - useMfcDynamic + useMfcDynamic }; enum warningLevelOption { warningLevel_0, warningLevel_1, warningLevel_2, warningLevel_3, @@ -387,34 +387,32 @@ enum warningLevelOption { }; class VCToolBase { protected: // Functions VCToolBase(){}; - ~VCToolBase(){}; + virtual ~VCToolBase(){} virtual bool parseOption( const char* option ) = 0; public: - bool parseOptions( QStringList& options ) { - bool result = TRUE; - for ( QStringList::ConstIterator it=options.begin(); (it!=options.end()) && result; it++ ) - result = parseOption( (*it).latin1() ); - return result; + void parseOptions( QStringList& options ) { + for ( QStringList::ConstIterator it=options.begin(); (it!=options.end()); it++ ) + parseOption( (*it).latin1() ); } }; class VCConfiguration; class VCProject; class VCCLCompilerTool : public VCToolBase { public: // Functions VCCLCompilerTool(); - ~VCCLCompilerTool(){}; - virtual bool parseOption( const char* option ); - + virtual ~VCCLCompilerTool(){} + bool parseOption( const char* option ); + // Variables QStringList AdditionalIncludeDirectories; QStringList AdditionalOptions; QStringList AdditionalUsingDirectories; QString AssemblerListingLocation; asmListingOption AssemblerOutput; @@ -477,14 +475,14 @@ public: class VCLinkerTool : public VCToolBase { public: // Functions VCLinkerTool(); - ~VCLinkerTool(){}; - virtual bool parseOption( const char* option ); + virtual ~VCLinkerTool(){} + bool parseOption( const char* option ); // Variables QStringList AdditionalDependencies; QStringList AdditionalLibraryDirectories; QStringList AdditionalOptions; QStringList AddModuleNamesToAssembly; @@ -542,14 +540,14 @@ public: class VCMIDLTool : public VCToolBase { public: // Functions VCMIDLTool(); - ~VCMIDLTool(){}; - virtual bool parseOption( const char* option ); + virtual ~VCMIDLTool(){} + bool parseOption( const char* option ); // Variables QStringList AdditionalIncludeDirectories; QStringList AdditionalOptions; QStringList CPreprocessOptions; midlCharOption DefaultCharType; @@ -584,14 +582,14 @@ public: class VCLibrarianTool : public VCToolBase { public: // Functions VCLibrarianTool(); - ~VCLibrarianTool(){}; - virtual bool parseOption( const char* option ){ return FALSE; }; + virtual ~VCLibrarianTool(){} + bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalDependencies; QStringList AdditionalLibraryDirectories; QStringList AdditionalOptions; QStringList ExportNamedFunctions; @@ -605,14 +603,14 @@ public: class VCCustomBuildTool : public VCToolBase { public: // Functions VCCustomBuildTool(); - ~VCCustomBuildTool(){}; - virtual bool parseOption( const char* option ){ return FALSE; }; + virtual ~VCCustomBuildTool(){} + bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalDependencies; QString CommandLine; QString Description; QString Outputs; @@ -622,14 +620,14 @@ public: class VCResourceCompilerTool : public VCToolBase { public: // Functions VCResourceCompilerTool(); - ~VCResourceCompilerTool(){}; - virtual bool parseOption( const char* option ){ return FALSE; }; + virtual ~VCResourceCompilerTool(){} + bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalIncludeDirectories; QStringList AdditionalOptions; enumResourceLangID Culture; QStringList FullIncludePath; @@ -642,51 +640,51 @@ public: class VCEventTool : public VCToolBase { protected: // Functions VCEventTool() : ExcludedFromBuild( unset ){}; - ~VCEventTool(){}; - virtual bool parseOption( const char* option ){ return FALSE; }; + virtual ~VCEventTool(){} + bool parseOption( const char* ){ return FALSE; }; public: // Variables QString CommandLine; QString Description; triState ExcludedFromBuild; QString ToolName; QString ToolPath; }; -class VCPostBuildEventTool : public VCEventTool +class VCPostBuildEventTool : public VCEventTool { public: VCPostBuildEventTool(); - ~VCPostBuildEventTool(){}; + ~VCPostBuildEventTool(){} }; -class VCPreBuildEventTool : public VCEventTool +class VCPreBuildEventTool : public VCEventTool { public: VCPreBuildEventTool(); - ~VCPreBuildEventTool(){}; + ~VCPreBuildEventTool(){} }; -class VCPreLinkEventTool : public VCEventTool +class VCPreLinkEventTool : public VCEventTool { public: VCPreLinkEventTool(); - ~VCPreLinkEventTool(){}; + ~VCPreLinkEventTool(){} }; class VCConfiguration { public: // Functions VCConfiguration(); - ~VCConfiguration(){}; + ~VCConfiguration(){} // Variables triState ATLMinimizesCRunTimeLibraryUsage; triState BuildBrowserInformation; charSet CharacterSet; ConfigurationTypes ConfigurationType; @@ -717,13 +715,13 @@ public: class VcprojGenerator; class VCFilter { public: // Functions VCFilter(); - ~VCFilter(){}; + ~VCFilter(){} void generateMOC( QTextStream &strm, QString str ) const; void generateUIC( QTextStream &strm, const QString& str ) const; // Variables QString Name; QString Filter; @@ -736,13 +734,13 @@ public: class VCProject { public: // Functions VCProject(); - ~VCProject(){}; + ~VCProject(){} // Variables QString Name; QString Version; QString ProjectGUID; QString SccProjectName; diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index a2bb6e9..d2cbc31 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of VcprojGenerator class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -35,68 +35,153 @@ ** **********************************************************************/ #include "msvc_vcproj.h" #include "option.h" #include <qdir.h> -#include <stdlib.h> #include <qregexp.h> +#include <qdict.h> +#include <quuid.h> +#include <stdlib.h> #if defined(Q_OS_WIN32) #include <objbase.h> +#ifndef GUID_DEFINED +#define GUID_DEFINED +typedef struct _GUID +{ + ulong Data1; + ushort Data2; + ushort Data3; + uchar Data4[8]; +} GUID; +#endif #endif +// Flatfile Tags ---------------------------------------------------- +const char* _snlHeader = "Microsoft Visual Studio Solution File, Format Version 7.00"; + // The following UUID _may_ change for later servicepacks... + // If so we need to search through the registry at + // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects + // to find the subkey that contains a "PossibleProjectExtension" + // containing "vcproj"... + // Use the hardcoded value for now so projects generated on other + // platforms are actually usable. +const char* _snlMSVCvcprojGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; +const char* _snlProjectBeg = "\nProject(\""; +const char* _snlProjectMid = "\") = "; +const char* _snlProjectEnd = "\nEndProject"; +const char* _snlGlobalBeg = "\nGlobal"; +const char* _snlGlobalEnd = "\nEndGlobal"; +const char* _snlSolutionConf = "\n\tGlobalSection(SolutionConfiguration) = preSolution" + "\n\t\tConfigName.0 = Release" + "\n\tEndGlobalSection"; +const char* _snlProjDepBeg = "\n\tGlobalSection(ProjectDependencies) = postSolution"; +const char* _snlProjDepEnd = "\n\tEndGlobalSection"; +const char* _snlProjConfBeg = "\n\tGlobalSection(ProjectConfiguration) = postSolution"; +const char* _snlProjConfTag1 = ".Release.ActiveCfg = Release|Win32"; +const char* _snlProjConfTag2 = ".Release.Build.0 = Release|Win32"; +const char* _snlProjConfEnd = "\n\tEndGlobalSection"; +const char* _snlExtSections = "\n\tGlobalSection(ExtensibilityGlobals) = postSolution" + "\n\tEndGlobalSection" + "\n\tGlobalSection(ExtensibilityAddIns) = postSolution" + "\n\tEndGlobalSection"; +// ------------------------------------------------------------------ + VcprojGenerator::VcprojGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) { } /* \internal Generates a project file for the given profile. Options are either a Visual Studio projectfiles, or - recursive projectfiles.. Maybe we can make .sln files - someday? + solutionfiles by parsing recursive projectdirectories. */ bool VcprojGenerator::writeMakefile(QTextStream &t) { // Check if all requirements are fullfilled if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", var("QMAKE_FAILED_REQUIREMENTS").latin1()); return TRUE; } - // Generate full project file + // Generate project file if(project->first("TEMPLATE") == "vcapp" || project->first("TEMPLATE") == "vclib") { debug_msg(1, "Generator: MSVC.NET: Writing project file" ); t << vcProject; return TRUE; - } else if(project->first("TEMPLATE") == "vcsubdirs") { // Generate recursive project + } + // Generate solution file + else if(project->first("TEMPLATE") == "vcsubdirs") { debug_msg(1, "Generator: MSVC.NET: Writing solution file" ); writeSubDirs(t); return TRUE; } return FALSE; } struct VcsolutionDepend { + QString uuid; QString vcprojFile, orig_target, target; + ::target targetType; QStringList dependencies; }; +QUuid VcprojGenerator::increaseUUID( const QUuid &id ) +{ + QUuid result( id ); + Q_LONG dataFirst = (result.data4[0] << 24) + + (result.data4[1] << 16) + + (result.data4[2] << 8) + + result.data4[3]; + Q_LONG dataLast = (result.data4[4] << 24) + + (result.data4[5] << 16) + + (result.data4[6] << 8) + + result.data4[7]; + + if ( !(dataLast++) ) + dataFirst++; + + result.data4[0] = uchar((dataFirst >> 24) & 0xff); + result.data4[1] = uchar((dataFirst >> 16) & 0xff); + result.data4[2] = uchar((dataFirst >> 8) & 0xff); + result.data4[3] = uchar( dataFirst & 0xff); + result.data4[4] = uchar((dataLast >> 24) & 0xff); + result.data4[5] = uchar((dataLast >> 16) & 0xff); + result.data4[6] = uchar((dataLast >> 8) & 0xff); + result.data4[7] = uchar( dataLast & 0xff); + return result; +} + void VcprojGenerator::writeSubDirs(QTextStream &t) { if(project->first("TEMPLATE") == "subdirs") { writeHeader(t); Win32MakefileGenerator::writeSubDirs(t); return; } - QPtrList<VcsolutionDepend> solution_depends; - solution_depends.setAutoDelete(TRUE); + t << _snlHeader; + QUuid solutionGUID; +#if defined(Q_WS_WIN32) + GUID guid; + HRESULT h = CoCreateGuid( &guid ); + if ( h == S_OK ) + solutionGUID = QUuid( guid ); +#else + // Qt doesn't support GUID on other platforms yet, + // so we use the all-zero uuid, and increase that. +#endif + + + QDict<VcsolutionDepend> solution_depends; + QPtrList<VcsolutionDepend> solution_cleanup; + solution_cleanup.setAutoDelete(TRUE); QStringList subdirs = project->variables()["SUBDIRS"]; QString oldpwd = QDir::currentDirPath(); for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) { QFileInfo fi(Option::fixPathToLocalOS((*it), TRUE)); if(fi.exists()) { if(fi.isDir()) { @@ -113,78 +198,109 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) fprintf(stderr, "Cannot find directory: %s\n", dir.latin1()); } if(tmp_proj.read(fn, oldpwd)) { if(tmp_proj.first("TEMPLATE") == "vcsubdirs") { QStringList tmp_subdirs = fileFixify(tmp_proj.variables()["SUBDIRS"]); subdirs += tmp_subdirs; - } else if(tmp_proj.first("TEMPLATE") == "vcapp" || - tmp_proj.first("TEMPLATE") == "vclib") { - QString vcproj = fi.baseName() + project->first("VCPROJ_EXTENSION"); - if(QFile::exists(vcproj) || 1) { - VcprojGenerator tmp_dsp(&tmp_proj); - tmp_dsp.setNoIO(TRUE); - tmp_dsp.init(); - if(Option::debug_level) { - QMap<QString, QStringList> &vars = tmp_proj.variables(); - for(QMap<QString, QStringList>::Iterator it = vars.begin(); - it != vars.end(); ++it) { - if(it.key().left(1) != "." && !it.data().isEmpty()) - debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(), - it.data().join(" :: ").latin1()); - } + } else if(tmp_proj.first("TEMPLATE") == "vcapp" || tmp_proj.first("TEMPLATE") == "vclib") { + // Initialize a 'fake' project to get the correct variables + // and to be able to extract all the dependencies + VcprojGenerator tmp_vcproj(&tmp_proj); + tmp_vcproj.setNoIO(TRUE); + tmp_vcproj.init(); + if(Option::debug_level) { + QMap<QString, QStringList> &vars = tmp_proj.variables(); + for(QMap<QString, QStringList>::Iterator it = vars.begin(); + it != vars.end(); ++it) { + if(it.key().left(1) != "." && !it.data().isEmpty()) + debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(), + it.data().join(" :: ").latin1()); } - VcsolutionDepend *newDep = new VcsolutionDepend; - newDep->vcprojFile = fileFixify(vcproj); - newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET"); - newDep->target = tmp_proj.first("TARGET").section(Option::dir_sep, -1); - if(newDep->target.endsWith(".dll")) - newDep->target = newDep->target.left(newDep->target.length()-3) + "lib"; - if(!tmp_proj.isEmpty("FORMS")) - newDep->dependencies << "uic.exe"; - { - QStringList where("QMAKE_LIBS"); - if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS")) - where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"]; - for(QStringList::iterator wit = where.begin(); - wit != where.end(); ++wit) { - QStringList &l = tmp_proj.variables()[(*wit)]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { - QString opt = (*it); - if(!opt.startsWith("/")) //Not a switch - newDep->dependencies << opt.section(Option::dir_sep, -1); - } + } + + // We assume project filename is [QMAKE_ORIG_TARGET].vcproj + QString vcproj = fixFilename(tmp_vcproj.project->first("QMAKE_ORIG_TARGET")) + project->first("VCPROJ_EXTENSION"); + + // If file doesn't exsist, then maybe the users configuration + // doesn't allow it to be created. Skip to next... + if(!QFile::exists(QDir::currentDirPath() + Option::dir_sep + vcproj)) { + qDebug( "Ignored (not found) '%s'", QString(QDir::currentDirPath() + Option::dir_sep + vcproj).latin1() ); + goto nextfile; // # Dirty! + } + + VcsolutionDepend *newDep = new VcsolutionDepend; + newDep->vcprojFile = fileFixify(vcproj); + newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET"); + newDep->target = tmp_proj.first("TARGET").section(Option::dir_sep, -1); + newDep->targetType = tmp_vcproj.projectTarget; + { + static QUuid uuid = solutionGUID; + uuid = increaseUUID( uuid ); + newDep->uuid = uuid.toString().upper(); + } + if(newDep->target.endsWith(".dll")) + newDep->target = newDep->target.left(newDep->target.length()-3) + "lib"; + if(!tmp_proj.isEmpty("FORMS")) + newDep->dependencies << "uic.exe"; + { + QStringList where("QMAKE_LIBS"); + if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS")) + where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"]; + for(QStringList::iterator wit = where.begin(); + wit != where.end(); ++wit) { + QStringList &l = tmp_proj.variables()[(*wit)]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QString opt = (*it); + if(!opt.startsWith("/")) //Not a switch + newDep->dependencies << opt.section(Option::dir_sep, -1); } } - solution_depends.append(newDep); } + solution_cleanup.append(newDep); + solution_depends.insert(newDep->target, newDep); + { + QRegExp libVersion("[0-9]{3,3}\\.lib$"); + if(libVersion.search(newDep->target) != -1) + solution_depends.insert(newDep->target.left(newDep->target.length() - + libVersion.matchedLength()) + ".lib", newDep); + } + t << _snlProjectBeg << _snlMSVCvcprojGUID << _snlProjectMid + << "\"" << newDep->orig_target << "\", \"" << newDep->vcprojFile + << "\", \"" << newDep->uuid << "\""; + t << _snlProjectEnd; } } +nextfile: QDir::setCurrent(oldpwd); } } } - - VcsolutionDepend *vc; - QMap<QString, int> uuids; - QRegExp libVersion("[0-9]{3,3}\\.lib$"); - for(vc = solution_depends.first(); vc; vc = solution_depends.next()) { - static int uuid = 666; - uuids.insert(vc->target, uuid); - if(libVersion.match(vc->target) != -1) - uuids.insert(vc->target.left(vc->target.length() - libVersion.matchedLength()) + ".lib", - uuid); - t << "\"" << vc->orig_target << "\" \"" << vc->vcprojFile << "\" { " << uuid << " }" << endl; - uuid++; - } - for(vc = solution_depends.first(); vc; vc = solution_depends.next()) { - int uuid = uuids[vc->target], cnt = 0; - for(QStringList::iterator dit = vc->dependencies.begin(); dit != vc->dependencies.end(); ++dit) { - if(uuids.contains((*dit))) - t << uuid << "." << cnt++ << " = " << uuids[(*dit)] << endl; + t << _snlGlobalBeg; + t << _snlSolutionConf; + t << _snlProjDepBeg; + for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { + int cnt = 0; + for(QStringList::iterator dit = solution_cleanup.current()->dependencies.begin(); + dit != solution_cleanup.current()->dependencies.end(); + ++dit) { + VcsolutionDepend *vc; + if((vc=solution_depends[*dit])) { + if(solution_cleanup.current()->targetType != StaticLib || vc->targetType == Application) + t << "\n\t\t" << solution_cleanup.current()->uuid << "." << cnt++ << " = " << vc->uuid; + } } } + t << _snlProjDepEnd; + t << _snlProjConfBeg; + for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { + t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag1; + t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag2; + } + t << _snlProjConfEnd; + t << _snlExtSections; + t << _snlGlobalEnd; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void VcprojGenerator::init() @@ -303,18 +419,18 @@ void VcprojGenerator::initConfiguration() break; case Application: default: vcProject.Configuration.ConfigurationType = typeApplication; break; } - vcProject.Configuration.Name = ( project->isActiveConfig( "release" ) ? "Release|" : "Debug|" ); + vcProject.Configuration.Name = ( project->isActiveConfig( "debug" ) ? "Debug|" : "Release|" ); vcProject.Configuration.Name += ( vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" ); vcProject.Configuration.ATLMinimizesCRunTimeLibraryUsage = ( project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True ); - vcProject.Configuration.BuildBrowserInformation = triState( temp.isEmpty() ? unset : temp.toShort() ); + vcProject.Configuration.BuildBrowserInformation = triState( temp.isEmpty() ? (short)unset : temp.toShort() ); temp = project->first("CharacterSet"); - vcProject.Configuration.CharacterSet = charSet( temp.isEmpty() ? charSetNotSet : temp.toShort() ); + vcProject.Configuration.CharacterSet = charSet( temp.isEmpty() ? (short)charSetNotSet : temp.toShort() ); vcProject.Configuration.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean"); vcProject.Configuration.ImportLibrary = vcProject.Configuration.linker.ImportLibrary; vcProject.Configuration.IntermediateDirectory = project->first("OBJECTS_DIR"); // temp = (projectTarget == StaticLib) ? project->first("DESTDIR"):project->first("DLLDESTDIR"); vcProject.Configuration.OutputDirectory = "."; //( temp.isEmpty() ? QString(".") : temp ); vcProject.Configuration.PrimaryOutput = project->first("PrimaryOutput"); @@ -335,13 +451,13 @@ void VcprojGenerator::initConfiguration() } void VcprojGenerator::initCompilerTool() { QString placement = project->first("OBJECTS_DIR"); if ( placement.isEmpty() ) - placement = project->isActiveConfig( "release" )? ".\\Release\\":".\\Debug\\"; + placement = ".\\"; vcProject.Configuration.compiler.AssemblerListingLocation = placement ; vcProject.Configuration.compiler.ProgramDataBaseFileName = placement ; vcProject.Configuration.compiler.ObjectFile = placement ; vcProject.Configuration.compiler.PrecompiledHeaderFile = placement + project->first("QMAKE_ORIG_TARGET") + ".pch"; @@ -359,12 +475,13 @@ void VcprojGenerator::initCompilerTool() } } else { // Release version vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_RELEASE"] ); vcProject.Configuration.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; + vcProject.Configuration.compiler.PreprocessorDefinitions += "NDEBUG"; if ( project->isActiveConfig("thread") ) { if ( (projectTarget == Application) || (projectTarget == StaticLib) ) vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); else vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] ); } else { @@ -372,13 +489,13 @@ void VcprojGenerator::initCompilerTool() } } // Common for both release and debug if ( project->isActiveConfig("warn_off") ) vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] ); - else + else if ( project->isActiveConfig("warn_on") ) vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] ); if ( project->isActiveConfig("windows") ) vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["MSVCPROJ_WINCONDEF"]; // Can this be set for ALL configs? // If so, use qmake.conf! @@ -405,19 +522,21 @@ void VcprojGenerator::initLibrarianTool() void VcprojGenerator::initLinkerTool() { vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LFLAGS"] ); vcProject.Configuration.linker.AdditionalDependencies += project->variables()["MSVCPROJ_LIBS"]; switch ( projectTarget ) { - case Application: - vcProject.Configuration.linker.OutputFile = project->first( "DESTDIR" ); - break; - case SharedLib: - vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] ); - vcProject.Configuration.linker.OutputFile = project->first( "DLLDESTDIR" ); - break; + case Application: + vcProject.Configuration.linker.OutputFile = project->first( "DESTDIR" ); + break; + case SharedLib: + vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] ); + vcProject.Configuration.linker.OutputFile = project->first( "DLLDESTDIR" ); + break; + case StaticLib: //unhandled - added to remove warnings.. + break; } if( vcProject.Configuration.linker.OutputFile.isEmpty() ) vcProject.Configuration.linker.OutputFile = ".\\"; if( !vcProject.Configuration.linker.OutputFile.endsWith("\\") ) @@ -456,30 +575,46 @@ void VcprojGenerator::initPreBuildEventTools() { QString collectionName = project->first("QMAKE_IMAGE_COLLECTION"); if( !collectionName.isEmpty() ) { QStringList& list = project->variables()["IMAGES"]; vcProject.Configuration.preBuild.Description = "Generate imagecollection"; //vcProject.Configuration.preBuild.AdditionalDependencies += list; - vcProject.Configuration.preBuild.CommandLine = project->first("QMAKE_UIC") + " -embed " + project->first("QMAKE_ORIG_TARGET") + " " + list.join(" ") + " -o " + collectionName; + + QFile imgs( ".imgcol" ); + imgs.open( IO_WriteOnly ); + QTextStream s( &imgs ); + QStringList::ConstIterator it = list.begin(); + while( it!=list.end() ) { + s << *it << " "; + it++; + } + + vcProject.Configuration.preBuild.CommandLine = project->first("QMAKE_UIC") + " -embed " + project->first("QMAKE_ORIG_TARGET") + " -f .imgcol -o " + collectionName; //vcProject.Configuration.preBuild.Outputs = collectionName; } } void VcprojGenerator::initPostBuildEventTools() { + if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) { + vcProject.Configuration.postBuild.Description = var("QMAKE_POST_LINK"); + vcProject.Configuration.postBuild.CommandLine = var("QMAKE_POST_LINK"); + } if( project->isActiveConfig( "activeqt" ) ) { QString name = project->first( "QMAKE_ORIG_TARGET" ); QString nameext = project->first( "TARGET" ); QString objdir = project->first( "OBJECTS_DIR" ); QString idc = project->first( "QMAKE_IDC" ); vcProject.Configuration.postBuild.Description = "Finalizing ActiveQt server..."; + if ( !vcProject.Configuration.postBuild.CommandLine.isEmpty() ) + vcProject.Configuration.postBuild.CommandLine += " && "; if( project->isActiveConfig( "dll" ) ) { // In process - vcProject.Configuration.postBuild.CommandLine = + vcProject.Configuration.postBuild.CommandLine += // call idc to generate .idl file from .dll idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " -idl " + objdir + name + ".idl -version 1.0 && " + // call midl to create implementations of the .idl file project->first( "QMAKE_IDL" ) + " " + objdir + name + ".idl /nologo /o " + objdir + name + ".midl /tlb " + objdir + name + ".tlb /iid " + objdir + "dump.midl /dlldata " + objdir + "dump.midl /cstub " + objdir + "dump.midl /header " + objdir + "dump.midl /proxy " + objdir + "dump.midl /sstub " + objdir + "dump.midl && " + @@ -599,39 +734,46 @@ void VcprojGenerator::initResourceFiles() vcProject.ResourceFiles.Files += project->variables()["IDLSOURCES"]; vcProject.ResourceFiles.Files.sort(); vcProject.ResourceFiles.Project = this; vcProject.ResourceFiles.CustomBuild = none; } -/* -// $$MSVCPROJ_IDLSOURCES --------------------------------------------- -void VcprojGenerator::writeIDLs( QTextStream &t ) -{ - QStringList &l = project->variables()["MSVCPROJ_IDLSOURCES"]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { - t << "# Begin Source File" << endl << endl; - t << "SOURCE=" << (*it) << endl; - t << "# PROP Exclude_From_Build 1" << endl; - t << "# End Source File" << endl << endl; - } - debug_msg(3, "Generator: MSVC.NET: Added IDLs" ); -} -*/ - /* \internal Sets up all needed variables from the environment and all the different caches and .conf files */ void VcprojGenerator::initOld() { if( init_flag ) return; init_flag = TRUE; QStringList::Iterator it; + if ( project->isActiveConfig("stl") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; + } + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + // this should probably not be here, but I'm using it to wrap the .t files if(project->first("TEMPLATE") == "vcapp" ) project->variables()["QMAKE_APP_FLAG"].append("1"); else if(project->first("TEMPLATE") == "vclib") project->variables()["QMAKE_LIB_FLAG"].append("1"); if ( project->variables()["QMAKESPEC"].isEmpty() ) @@ -785,23 +927,36 @@ void VcprojGenerator::initOld() project->variables()["MSVCPROJ_VER"] = "7.00"; project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /ZI"; // INCREMENTAL:NO ------------------------------------------------ if(!project->isActiveConfig("incremental")) { - project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no")); + project->variables()["QMAKE_LFLAGS"].append(QString("/INCREMENTAL:no")); if ( is_qt ) project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /Zi"; } // MOC ----------------------------------------------------------- if ( project->isActiveConfig("moc") ) setMocAware(TRUE); project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + // Update -lname to name.lib, and -Ldir to + QStringList &libList = project->variables()["QMAKE_LIBS"]; + for( it = libList.begin(); it != libList.end(); ) { + QString s = *it; + if( s.startsWith( "-l" ) ) { + it = libList.remove( it ); + it = libList.insert( it, s.mid( 2 ) + ".lib" ); + } else if( s.startsWith( "-L" ) ) { + it = libList.remove( it ); + } else { + it++; + } + } // Run through all variables containing filepaths, and ----------- // slash-slosh them correctly depending on current OS ----------- project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); QStringList &l = project->variables()["QMAKE_FILETAGS"]; for(it = l.begin(); it != l.end(); ++it) { @@ -818,14 +973,14 @@ void VcprojGenerator::initOld() targetfilename = msvcproj_project; } // Save filename w/o extention in $$QMAKE_ORIG_TARGET ------------ project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; - // TARGET (add extention to $$TARGET) ---------------------------- - project->variables()["TARGET"].first() += project->first("TARGET_EXT"); + // TARGET (add extention to $$TARGET) + //project->variables()["MSVCPROJ_DEFINES"].append(varGlue(".first() += project->first("TARGET_EXT"); // Init base class too ------------------------------------------- MakefileGenerator::init(); if ( msvcproj_project.isEmpty() ) @@ -864,14 +1019,21 @@ void VcprojGenerator::initOld() } // $$QMAKE.. -> $$MSVCPROJ.. ------------------------------------- project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS"]; project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; project->variables()["MSVCPROJ_LFLAGS" ] += project->variables()["QMAKE_LFLAGS"]; - if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) - project->variables()["MSVCPROJ_LFLAGS" ].append(varGlue("QMAKE_LIBDIR","/LIBPATH:"," /LIBPATH:","")); + if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) { + QStringList strl = project->variables()["QMAKE_LIBDIR"]; + QStringList::iterator stri; + for ( stri = strl.begin(); stri != strl.end(); ++stri ) { + if ( !(*stri).startsWith("/LIBPATH:") ) + (*stri).prepend( "/LIBPATH:" ); + } + project->variables()["MSVCPROJ_LFLAGS"] += strl; + } project->variables()["MSVCPROJ_CXXFLAGS" ] += project->variables()["QMAKE_CXXFLAGS"]; // We don't use this... Direct manipulation of compiler object //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("DEFINES","/D ","" " /D ","")); //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ","")); QStringList &incs = project->variables()["INCLUDEPATH"]; for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { @@ -880,25 +1042,24 @@ void VcprojGenerator::initOld() project->variables()["MSVCPROJ_INCPATH"].append("/I" + inc ); } project->variables()["MSVCPROJ_INCPATH"].append("/I" + specdir()); QString dest; project->variables()["MSVCPROJ_TARGET"] = project->first("TARGET"); - if ( !project->variables()["DESTDIR"].isEmpty() ) { - project->variables()["TARGET"].first().prepend(project->first("DESTDIR")); - Option::fixPathToTargetOS(project->first("TARGET")); - dest = project->first("TARGET"); - if ( project->first("TARGET").startsWith("$(QTDIR)") ) - dest.replace( QRegExp("\\$\\(QTDIR\\)"), getenv("QTDIR") ); - project->variables()["MSVCPROJ_TARGET"].append( - QString("/OUT:") + dest ); - if ( project->isActiveConfig("dll") ) { - QString imp = dest; - imp.replace(QRegExp("\\.dll"), ".lib"); - project->variables()["MSVCPROJ_LIBOPTIONS"] += (QString("/IMPLIB:") + imp ); - } + Option::fixPathToTargetOS(project->first("TARGET")); + dest = project->first("TARGET") + project->first( "TARGET_EXT" ); + if ( project->first("TARGET").startsWith("$(QTDIR)") ) + dest.replace( QRegExp("\\$\\(QTDIR\\)"), getenv("QTDIR") ); + project->variables()["MSVCPROJ_TARGET"] = dest; + if ( project->isActiveConfig("dll") ) { + QString imp = project->first( "DESTDIR" ); + if( !imp.isNull() && !imp.endsWith( "\\" ) ) + imp += "\\"; + imp += dest; + imp.replace(QRegExp("\\.dll"), ".lib"); + project->variables()["MSVCPROJ_LIBOPTIONS"] += QString("/IMPLIB:") + imp; } // DLL COPY ------------------------------------------------------ if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; QString copydll = "# Begin Special Build Tool\n" @@ -993,29 +1154,32 @@ bool VcprojGenerator::openOutput(QFile &file) const QString ext = project->first("VCPROJ_EXTENSION"); if(project->first("TEMPLATE") == "vcsubdirs") ext = project->first("VCSOLUTION_EXTENSION"); file.setName(outdir + project->first("TARGET") + ext); } if(QDir::isRelativePath(file.name())) { - QString ofile; - ofile = file.name(); - int slashfind = ofile.findRev('\\'); - if (slashfind == -1) { - ofile = ofile.replace("-", "_"); - } else { - int hypenfind = ofile.find('-', slashfind); - while (hypenfind != -1 && slashfind < hypenfind) { - ofile = ofile.replace(hypenfind, 1, "_"); - hypenfind = ofile.find('-', hypenfind + 1); - } - } - file.setName(Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + ofile)); + file.setName( Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + fixFilename(file.name())) ); } return Win32MakefileGenerator::openOutput(file); } +QString VcprojGenerator::fixFilename(QString ofile) const +{ + int slashfind = ofile.findRev('\\'); + if (slashfind == -1) { + ofile = ofile.replace('-', '_'); + } else { + int hypenfind = ofile.find('-', slashfind); + while (hypenfind != -1 && slashfind < hypenfind) { + ofile = ofile.replace(hypenfind, 1, '_'); + hypenfind = ofile.find('-', hypenfind + 1); + } + } + return ofile; +} + QString VcprojGenerator::findTemplate(QString file) { QString ret; if(!QFile::exists((ret = file)) && !QFile::exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) && !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/win32-msvc.net/" + file)) && @@ -1039,12 +1203,12 @@ void VcprojGenerator::processPrlVariable(const QString &var, const QStringList & } } void VcprojGenerator::outputVariables() { #if 0 - debug_msg(3, "Generator: MSVC.NET: List of current variables:" ); + qDebug( "Generator: MSVC.NET: List of current variables:" ); for ( QMap<QString, QStringList>::ConstIterator it = project->variables().begin(); it != project->variables().end(); ++it) { - debug_msg(3, "Generator: MSVC.NET: %s => %s", it.key().latin1(), it.data().join(" | ").latin1() ); + qDebug( "Generator: MSVC.NET: %s => %s", it.key().latin1(), it.data().join(" | ").latin1() ); } #endif } diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 583b164..69e0c02 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of VcprojGenerator class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -31,24 +31,25 @@ ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef __VCPROJMAKE_H__ -#define __VCPROJMAKE_H__ +#ifndef __MSVC_VCPROJ_H__ +#define __MSVC_VCPROJ_H__ #include "winmakefile.h" #include "msvc_objectmodel.h" enum target { Application, SharedLib, StaticLib }; +struct QUuid; class VcprojGenerator : public Win32MakefileGenerator { bool init_flag; bool writeVcprojParts(QTextStream &); bool writeMakefile(QTextStream &); @@ -65,12 +66,13 @@ public: protected: virtual bool openOutput(QFile &file) const; virtual void processPrlVariable(const QString &, const QStringList &); virtual bool findLibraries(); virtual void outputVariables(); + QString fixFilename(QString ofile) const; void initOld(); void initProject(); void initConfiguration(); void initCompilerTool(); void initLinkerTool(); @@ -86,33 +88,17 @@ protected: void initUICFiles(); void initFormsFiles(); void initTranslationFiles(); void initLexYaccFiles(); void initResourceFiles(); - /* - void writeGuid( QTextStream &t ); - void writeAdditionalOptions( QTextStream &t ); - void writeHeaders( QTextStream &t ); - void writeSources( QTextStream &t ); - void writeMocs( QTextStream &t ); - void writeLexs( QTextStream &t ); - void writeYaccs( QTextStream &t ); - void writePictures( QTextStream &t ); - void writeImages( QTextStream &t ); - void writeIDLs( QTextStream &t ); - - void writeForms( QTextStream &t ); - void writeFormsSourceHeaders( QString &variable, QTextStream &t ); - void writeTranslations( QTextStream &t ); - void writeStrippedTranslations( QTextStream &t ); - */ - VCProject vcProject; target projectTarget; +private: + QUuid increaseUUID(const QUuid &id); friend class VCFilter; }; inline VcprojGenerator::~VcprojGenerator() { } @@ -123,7 +109,7 @@ inline QString VcprojGenerator::defaultMakefile() const inline bool VcprojGenerator::findLibraries() { return Win32MakefileGenerator::findLibraries("MSVCVCPROJ_LIBS"); } -#endif /* __VCPROJMAKE_H__ */ +#endif /* __MSVC_VCPROJ_H__ */ diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index a07c921..bc3fed9 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -98,13 +98,13 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) QPtrListIterator<SubDir> it(subdirs); if(!project->isEmpty("MAKEFILE")) t << "MAKEFILE= " << var("MAKEFILE") << endl; t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; t << "SUBTARGETS = "; - for( it.toFirst(); it.current(); ++it) + for( it.toFirst(); it.current(); ++it) t << " \\\n\t\t" << it.current()->target; t << endl << endl; t << "all: qmake_all $(SUBTARGETS)" << endl << endl; for( it.toFirst(); it.current(); ++it) { bool have_dir = !(*it)->directory.isEmpty(); @@ -113,34 +113,32 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) QString mkfile = (*it)->makefile; if(have_dir) mkfile.prepend((*it)->directory + Option::dir_sep); t << mkfile << ":"; if(project->variables()["QMAKE_NOFORCE"].isEmpty()) t << " FORCE"; - if(have_dir) + if(have_dir) t << "\n\t" << "cd " << (*it)->directory; t << "\n\t" << "$(QMAKE) " << (*it)->profile << " " << buildArgs(); - if((*it)->makefile != "$(MAKEFILE)") - t << " -o " << (*it)->makefile; + t << " -o " << (*it)->makefile; if(have_dir) { int subLevels = it.current()->directory.contains(Option::dir_sep) + 1; t << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } t << endl; //now actually build t << (*it)->target << ": " << mkfile; if(project->variables()["QMAKE_NOFORCE"].isEmpty()) t << " FORCE"; - if(have_dir) + if(have_dir) t << "\n\t" << "cd " << (*it)->directory; t << "\n\t" << "$(MAKE)"; - if((*it)->makefile != "$(MAKEFILE)") - t << " -f " << (*it)->makefile; + t << " -f " << (*it)->makefile; if(have_dir) { int subLevels = it.current()->directory.contains(Option::dir_sep) + 1; t << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } @@ -152,20 +150,22 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) writeMakeQmake(t); t << "qmake_all:"; if ( !subdirs.isEmpty() ) { for( it.toFirst(); it.current(); ++it) { QString subdir = (*it)->directory; + QString profile = (*it)->profile; int subLevels = subdir.contains(Option::dir_sep) + 1; t << "\n\t" << "cd " << subdir << "\n\t"; int lastSlash = subdir.findRev(Option::dir_sep); if(lastSlash != -1) subdir = subdir.mid( lastSlash + 1 ); - t << "$(QMAKE) " << subdir << ".pro" - << (!project->isEmpty("MAKEFILE") ? QString(" -o ") + var("MAKEFILE") : QString("")) + t << "$(QMAKE) " + << ( !profile.isEmpty() ? profile : subdir + ".pro" ) + << " -o " << (*it)->makefile << " " << buildArgs() << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } } else { @@ -183,19 +183,17 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) if (!subdirs.isEmpty()) { for( it.toFirst(); it.current(); ++it) { int subLevels = (*it)->directory.contains(Option::dir_sep) + 1; bool have_dir = !(*it)->directory.isEmpty(); if(have_dir) t << "\n\t" << "cd " << (*it)->directory; - QString in_file; - if((*it)->makefile != "$(MAKEFILE)") - in_file = " -f " + (*it)->makefile; + QString in_file = " -f " + (*it)->makefile; t << "\n\t" << "$(MAKE) " << in_file << " " << targs[x]; if(have_dir) { t << "\n\t" << "@cd .."; - for(int i = 1; i < subLevels; i++ ) + for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } } } else { // Borland make does not like empty an empty command section, so // insert a dummy command. @@ -207,97 +205,139 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) if(project->variables()["QMAKE_NOFORCE"].isEmpty()) t << "FORCE:" << endl << endl; } int -Win32MakefileGenerator::findHighestVersion(const QString &d, const - QString &stem) +Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem) { - if(!QFile::exists(Option::fixPathToLocalOS(d))) + QString bd = Option::fixPathToLocalOS(d, TRUE); + if(!QFile::exists(bd)) return -1; - if(!project->variables()["QMAKE_" + stem.upper() + - "_VERSION_OVERRIDE"].isEmpty()) - return project->variables()["QMAKE_" + stem.upper() + - "_VERSION_OVERRIDE"].first().toInt(); - QString bd = d; - fixEnvVariables(bd); + if(!project->variables()["QMAKE_" + stem.upper() + "_VERSION_OVERRIDE"].isEmpty()) + return project->variables()["QMAKE_" + stem.upper() + "_VERSION_OVERRIDE"].first().toInt(); + QDir dir(bd); int biggest=-1; QStringList entries = dir.entryList(); - QRegExp regx( "(" + stem + "([0-9]*)).lib", FALSE ); - for(QStringList::Iterator it = entries.begin(); it != entries.end(); - ++it) { + QString dllStem = stem + QTDLL_POSTFIX; + QRegExp regx( "(" + dllStem + "([0-9]*)).lib", FALSE ); + for(QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) { if(regx.exactMatch((*it))) - biggest = QMAX(biggest, (regx.cap(1) == stem || - regx.cap(2).isEmpty()) ? -1 : regx.cap(2).toInt()); + biggest = QMAX(biggest, (regx.cap(1) == dllStem || + regx.cap(2).isEmpty()) ? -1 : regx.cap(2).toInt()); + } + if(dir.exists(dllStem + Option::prl_ext)) { + QMakeProject proj; + if(proj.read(bd + dllStem + Option::prl_ext, QDir::currentDirPath(), TRUE)) { + if(!proj.isEmpty("QMAKE_PRL_VERSION")) + biggest = QMAX(biggest, proj.first("QMAKE_PRL_VERSION").replace(".", "").toInt()); + } } return biggest; } bool Win32MakefileGenerator::findLibraries(const QString &where) { QStringList &l = project->variables()[where]; QPtrList<MakefileDependDir> dirs; + { + QStringList &libpaths = project->variables()["QMAKE_LIBDIR"]; + for(QStringList::Iterator libpathit = libpaths.begin(); libpathit != libpaths.end(); ++libpathit) { + QString r = (*libpathit), l = r; + fixEnvVariables(l); + dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); + } + } dirs.setAutoDelete(TRUE); for(QStringList::Iterator it = l.begin(); it != l.end(); ) { - QString opt = (*it); - bool remove = FALSE; - if(opt.startsWith("-L") || opt.startsWith("/L")) { - QString r = opt.right(opt.length() - 2), l = Option::fixPathToLocalOS(r); + QChar quote; + bool modified_opt = FALSE, remove = FALSE; + QString opt = (*it).stripWhiteSpace(); + if((opt[0] == '\'' || opt[0] == '"') && opt[(int)opt.length()-1] == opt[0]) { + quote = opt[0]; + opt = opt.mid(1, opt.length()-2); + } + if(opt.startsWith("/LIBPATH:")) { + QString r = opt.mid(9), l = Option::fixPathToLocalOS(r); + dirs.append(new MakefileDependDir(r.replace("\"",""), + l.replace("\"",""))); + } else if(opt.startsWith("-L") || opt.startsWith("/L")) { + QString r = opt.mid(2), l = Option::fixPathToLocalOS(r); dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); - remove = TRUE; + remove = TRUE; //we eat this switch } else if(opt.startsWith("-l") || opt.startsWith("/l")) { QString lib = opt.right(opt.length() - 2), out; if(!lib.isEmpty()) { for(MakefileDependDir *mdd = dirs.first(); mdd; mdd = dirs.next() ) { + QString extension; int ver = findHighestVersion(mdd->local_dir, lib); if(ver > 0) - lib += QString::number(ver); - lib += ".lib"; - if(QFile::exists(mdd->local_dir + Option::dir_sep + lib)) { - out = mdd->real_dir + Option::dir_sep + lib; + extension += QString::number(ver); + extension += ".lib"; + if(QFile::exists(mdd->local_dir + Option::dir_sep + lib + Option::prl_ext) || + QFile::exists(mdd->local_dir + Option::dir_sep + lib + extension)) { + out = mdd->real_dir + Option::dir_sep + lib + extension; break; } } } - if(out.isEmpty()) - remove = TRUE; - else + if(out.isEmpty()) { + remove = TRUE; //just eat it since we cannot find one.. + } else { + modified_opt = TRUE; (*it) = out; + } } else if(!QFile::exists(Option::fixPathToLocalOS(opt))) { - QString dir, file = opt; + QPtrList<MakefileDependDir> lib_dirs; + QString file = opt; int slsh = file.findRev(Option::dir_sep); if(slsh != -1) { - dir = file.left(slsh+1); + QString r = file.left(slsh+1), l = r; + fixEnvVariables(l); + lib_dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); file = file.right(file.length() - slsh - 1); - } - if ( !(project->variables()["QMAKE_QT_DLL"].isEmpty() && (file == "qt.lib" || file == "qt-mt.lib")) ) { - if(file.endsWith(".lib")) { - file = file.left(file.length() - 4); - if(!file.at(file.length()-1).isNumber()) { - int ver = findHighestVersion(dir, file); + } else { + lib_dirs = dirs; + } + if(file.endsWith(".lib")) { + file = file.left(file.length() - 4); + if(!file.at(file.length()-1).isNumber()) { + for(MakefileDependDir *mdd = lib_dirs.first(); mdd; mdd = lib_dirs.next() ) { + QString lib_tmpl(file + "%1" + ".lib"); + int ver = findHighestVersion(mdd->local_dir, file); if(ver != -1) { - file = QString(dir + file + "%1" + ".lib"); if(ver) - (*it) = file.arg(ver); + lib_tmpl = lib_tmpl.arg(ver); else - (*it) = file.arg(""); + lib_tmpl = lib_tmpl.arg(""); + if(slsh != -1) { + QString dir = mdd->real_dir; + if(!dir.endsWith(Option::dir_sep)) + dir += Option::dir_sep; + lib_tmpl.prepend(dir); + } + modified_opt = TRUE; + (*it) = lib_tmpl; + break; } } } } } - if(remove) + if(remove) { it = l.remove(it); - else + } else { + if(!quote.isNull() && modified_opt) + (*it) = quote + (*it) + quote; ++it; + } } return TRUE; } void Win32MakefileGenerator::processPrlFiles() @@ -320,14 +360,14 @@ Win32MakefileGenerator::processPrlFiles() QString where = "QMAKE_LIBS"; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) where = project->first("QMAKE_INTERNAL_PRL_LIBS"); QStringList &l = project->variables()[where]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString opt = (*it); - if(opt.left(1) == "/") { - if(opt.left(9) == "/LIBPATH:") { + if(opt.startsWith("/")) { + if(opt.startsWith("/LIBPATH:")) { QString r = opt.mid(9), l = r; fixEnvVariables(l); libdirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } } else { diff --git a/qmake/include/private/qapplication_p.h b/qmake/include/private/qapplication_p.h index 6fab6b3..280992e 100644 --- a/qmake/include/private/qapplication_p.h +++ b/qmake/include/private/qapplication_p.h @@ -70,18 +70,19 @@ extern bool qt_is_gui_used; #ifndef QT_NO_CLIPBOARD extern QClipboard *qt_clipboard; #endif #if defined (Q_OS_WIN32) || defined (Q_OS_CYGWIN) extern Qt::WindowsVersion qt_winver; +#elif defined (Q_OS_MAC) +extern Qt::MacintoshVersion qt_macver; #endif #if defined (Q_WS_X11) extern int qt_ncols_option; #endif extern void qt_dispatchEnterLeave( QWidget*, QWidget* ); - - +extern bool qt_tryModalHelper( QWidget *, QWidget ** = 0 ); #endif diff --git a/qmake/include/private/qcom_p.h b/qmake/include/private/qcom_p.h index 6e7e1c8..5bed8c8c 100644 --- a/qmake/include/private/qcom_p.h +++ b/qmake/include/private/qcom_p.h @@ -30,14 +30,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QCOM_H -#define QCOM_H +#ifndef QCOM_P_H +#define QCOM_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience @@ -331,7 +331,7 @@ public: \ # endif # define Q_EXPORT_INTERFACE() Q_EXPORT_COMPONENT() #endif #endif //QT_NO_COMPONENT -#endif //QCOM_H +#endif //QCOM_P_H diff --git a/qmake/include/private/qcomlibrary_p.h b/qmake/include/private/qcomlibrary_p.h index f52f679..3f440c0 100644 --- a/qmake/include/private/qcomlibrary_p.h +++ b/qmake/include/private/qcomlibrary_p.h @@ -30,14 +30,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QUCOMLIBRARY_H -#define QUCOMLIBRARY_H +#ifndef QCOMLIBRARY_P_H +#define QCOMLIBRARY_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience @@ -73,7 +73,7 @@ private: uint qt_version; }; #endif //QT_NO_COMPONENT -#endif // QUCOMLIBRARY_H +#endif diff --git a/qmake/include/private/qcomplextext_p.h b/qmake/include/private/qcomplextext_p.h index 2132522..c3aeeb1 100644 --- a/qmake/include/private/qcomplextext_p.h +++ b/qmake/include/private/qcomplextext_p.h @@ -1,14 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Internal header file. ** -** Created : -** -** Copyright (C) 2001 Trolltech AS. All rights reserved. +** Copyright (C) 2001-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -32,14 +30,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QCOMPLEXTEXT_H -#define QCOMPLEXTEXT_H +#ifndef QCOMPLEXTEXT_P_H +#define QCOMPLEXTEXT_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience diff --git a/qmake/include/private/qcomponentfactory_p.h b/qmake/include/private/qcomponentfactory_p.h index 1ac973f..d5c1743 100644 --- a/qmake/include/private/qcomponentfactory_p.h +++ b/qmake/include/private/qcomponentfactory_p.h @@ -32,14 +32,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QCOMPONENTFACTORY_H -#define QCOMPONENTFACTORY_H +#ifndef QCOMPONENTFACTORY_P_H +#define QCOMPONENTFACTORY_P_H #ifndef QT_H #include "qcom_p.h" #endif // QT_H // @@ -67,7 +67,7 @@ public: int version = 0, const QString &description = QString::null ); static bool unregisterComponent( const QUuid &cid ); }; #endif // QT_NO_COMPONENT -#endif // QCOMPONENTFACTORY_H +#endif // QCOMPONENTFACTORY_P_H diff --git a/qmake/include/private/qcriticalsection_p.h b/qmake/include/private/qcriticalsection_p.h index 7d9feca..8dacc62 100644 --- a/qmake/include/private/qcriticalsection_p.h +++ b/qmake/include/private/qcriticalsection_p.h @@ -30,14 +30,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QCRITICALSECTION_H -#define QCRITICALSECTION_H +#ifndef QCRITICALSECTION_P_H +#define QCRITICALSECTION_P_H #ifndef QT_H #endif // QT_H // // W A R N I N G diff --git a/qmake/include/private/qdir_p.h b/qmake/include/private/qdir_p.h index 35dba28..a6c7c91 100644 --- a/qmake/include/private/qdir_p.h +++ b/qmake/include/private/qdir_p.h @@ -1,12 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Definition of some private QDir functions. ** -** Created : 2000.11.06 +** Created : 001106 ** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License @@ -35,13 +35,12 @@ ** **********************************************************************/ #ifndef QDIR_P_H #define QDIR_P_H - // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience // of qdir.cpp and qdir_*.cpp. @@ -50,16 +49,18 @@ // // We mean it. // // #ifndef QT_H +#include "qregexp.h" +#include "qvaluelist.h" #endif // QT_H -extern QStringList qt_makeFilterList( const QString & ); - +extern QValueList<QRegExp> qt_makeFilterList( const QString & ); +extern bool qt_matchFilterList( const QValueList<QRegExp> &, const QString & ); extern int qt_cmp_si_sortSpec; #if defined(Q_C_CALLBACKS) extern "C" { #endif diff --git a/qmake/include/private/qeffects_p.h b/qmake/include/private/qeffects_p.h index 4178b6f..3b6c212 100644 --- a/qmake/include/private/qeffects_p.h +++ b/qmake/include/private/qeffects_p.h @@ -1,12 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Definition of QEffects functions ** -** Created : 2000.06.21 +** Created : 000621 ** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of the widgets module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License diff --git a/qmake/include/private/qeventloop_p.h b/qmake/include/private/qeventloop_p.h index b64d0df..3a5350e 100644 --- a/qmake/include/private/qeventloop_p.h +++ b/qmake/include/private/qeventloop_p.h @@ -1,17 +1,67 @@ +/**************************************************************************** +** $Id$ +** +** Definition of QEventLoop class +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of the kernel module of the Qt GUI Toolkit. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses for Qt/Embedded may use this file in accordance with the +** Qt Embedded Commercial License Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + #ifndef QEVENTLOOP_P_H #define QEVENTLOOP_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// + #include "qplatformdefs.h" + +// SCO OpenServer redefines raise -> kill +#if defined(raise) +# undef raise +#endif + #include "qwindowdefs.h" class QSocketNotifier; -#if defined(Q_OS_UNIX) +#if defined(Q_OS_UNIX) || defined (Q_WS_WIN) #include <qptrlist.h> +#endif // Q_OS_UNIX || Q_WS_WIN +#if defined(Q_OS_UNIX) struct QSockNot { QSocketNotifier *obj; int fd; fd_set *queue; }; @@ -27,12 +77,18 @@ public: fd_set enabled_fds; fd_set pending_fds; }; #endif // Q_OS_UNIX +#if defined(Q_WS_WIN) +struct QSockNot { + QSocketNotifier *obj; + int fd; +}; +#endif // Q_WS_WIN class QEventLoopPrivate { public: QEventLoopPrivate() { @@ -41,18 +97,20 @@ public: void reset() { looplevel = 0; quitcode = 0; quitnow = FALSE; exitloop = FALSE; + shortcut = FALSE; } int looplevel; int quitcode; - bool quitnow; - bool exitloop; + unsigned int quitnow : 1; + unsigned int exitloop : 1; + unsigned int shortcut : 1; #if defined(Q_WS_MAC) EventLoopTimerRef select_timer; #endif #if defined(Q_WS_X11) @@ -66,9 +124,15 @@ public: QPtrList<QSockNot> sn_pending_list; // highest fd for all socket notifiers int sn_highest; // 3 socket notifier types - read, write and exception QSockNotType sn_vec[3]; #endif + +#ifdef Q_WS_WIN + // pending socket notifiers list + QPtrList<QSockNot> sn_pending_list; +#endif // Q_WS_WIN + }; #endif // QEVENTLOOP_P_H diff --git a/qmake/include/private/qfontcodecs_p.h b/qmake/include/private/qfontcodecs_p.h index 8222f98..54b0ac1 100644 --- a/qmake/include/private/qfontcodecs_p.h +++ b/qmake/include/private/qfontcodecs_p.h @@ -48,14 +48,14 @@ // // We mean it. // // #ifndef QT_H -#include <qglobal.h> -#include <qtextcodec.h> +#include "qglobal.h" +#include "qtextcodec.h" #endif // QT_H #ifndef QT_NO_CODECS #ifndef QT_NO_BIG_CODECS diff --git a/qmake/include/private/qfontdata_p.h b/qmake/include/private/qfontdata_p.h index 917d14f..1eaf80c 100644 --- a/qmake/include/private/qfontdata_p.h +++ b/qmake/include/private/qfontdata_p.h @@ -159,12 +159,13 @@ public: QString k; HDC hdc; HFONT hfont; uint stockFont:1; uint paintDevice:1; + uint useTextOutA:1; union { TEXTMETRICW w; TEXTMETRICA a; } tm; int lw; int cache_cost; @@ -410,13 +411,13 @@ public: int textWidth( const QString &str, int pos, int len, TextRun *cache ); void drawText( QGfx *gfx, int x, int y, const TextRun *cache ); #endif #if defined( Q_WS_MAC ) void macSetFont(QPaintDevice *); - void drawText(int x, int y, QString s, int len, QPaintDevice *dev, const QRegion *rgn); + void drawText(int x, int y, const QString &s, int from, int len, QPaintDevice *dev, const QRegion *rgn, int dir); void computeLineWidth(); void load(); QFontStruct *fin; #endif }; diff --git a/qmake/include/private/qgfxdriverinterface_p.h b/qmake/include/private/qgfxdriverinterface_p.h index 1782ed4..e8259ac 100644 --- a/qmake/include/private/qgfxdriverinterface_p.h +++ b/qmake/include/private/qgfxdriverinterface_p.h @@ -27,14 +27,26 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QGFXDRIVERINTERFACE_H -#define QGFXDRIVERINTERFACE_H +#ifndef QGFXDRIVERINTERFACE_P_H +#define QGFXDRIVERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// #ifndef QT_H #include <private/qcom_p.h> #endif // QT_H #ifndef QT_NO_COMPONENT @@ -50,7 +62,7 @@ struct Q_EXPORT QGfxDriverInterface : public QFeatureListInterface { virtual QScreen* create( const QString& driver, int displayId ) = 0; }; #endif // QT_NO_COMPONENT -#endif // QGFXDRIVERINTERFACE_H +#endif // QGFXDRIVERINTERFACE_P_H diff --git a/qmake/include/private/qgpluginmanager_p.h b/qmake/include/private/qgpluginmanager_p.h index e0c0e78..2e4e9c5 100644 --- a/qmake/include/private/qgpluginmanager_p.h +++ b/qmake/include/private/qgpluginmanager_p.h @@ -1,12 +1,12 @@ /********************************************************************** ** $Id$ ** ** Definition of QGPluginManager class ** -** Copyright (C) 2000-2001 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -30,14 +30,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QGPLUGINMANAGER_H -#define QGPLUGINMANAGER_H +#ifndef QGPLUGINMANAGER_P_H +#define QGPLUGINMANAGER_P_H #ifndef QT_H #include "qdict.h" #include "qlibrary.h" #include "quuid.h" #include "qstringlist.h" @@ -101,7 +101,7 @@ inline bool QGPluginManager::autoUnload() const { return autounload; } #endif -#endif //QGPLUGINMANAGER_H +#endif //QGPLUGINMANAGER_P_H diff --git a/qmake/include/private/qimageformatinterface_p.h b/qmake/include/private/qimageformatinterface_p.h index 5f7601c..fd4c256 100644 --- a/qmake/include/private/qimageformatinterface_p.h +++ b/qmake/include/private/qimageformatinterface_p.h @@ -1,10 +1,10 @@ /**************************************************************************** ** $Id$ ** -** Definition of ??? +** ... ** ** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License @@ -30,14 +30,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QIMAGEFORMATINTERFACE_H -#define QIMAGEFORMATINTERFACE_H +#ifndef QIMAGEFORMATINTERFACE_P_H +#define QIMAGEFORMATINTERFACE_P_H #ifndef QT_H #include <private/qcom_p.h> #endif // QT_H @@ -69,7 +69,7 @@ struct Q_EXPORT QImageFormatInterface : public QFeatureListInterface virtual QRESULT installIOHandler( const QString & ) = 0; }; #endif // QT_NO_COMPONENT -#endif // QIMAGEFORMATINTERFACE_H +#endif // QIMAGEFORMATINTERFACE_P_H diff --git a/qmake/include/private/qinputcontext_p.h b/qmake/include/private/qinputcontext_p.h index 9ac0d2b..4d94147 100644 --- a/qmake/include/private/qinputcontext_p.h +++ b/qmake/include/private/qinputcontext_p.h @@ -84,13 +84,13 @@ public: void reset(); int lookupString(XKeyEvent *, QCString &, KeySym *, Status *) const; void setXFontSet(const QFont &); void *ic; - QString text, lastcompose; + QString text; QWidget *focusWidget; bool composing; QFont font; XFontSet fontset; QMemArray<bool> selectedChars; #endif // Q_WS_X11 @@ -112,10 +112,13 @@ private: static void setFont( const QWidget *w, const QFont & ); static void setFocusHint( int x, int y, int w, int h, const QWidget *widget ); static bool startComposition(); static bool endComposition( QWidget *fw = 0 ); static bool composition( LPARAM lparam ); + + static void accept( QWidget *fw = 0 ); + static void enable( bool ); #endif }; #endif // QINPUTCONTEXT_P_H diff --git a/qmake/include/private/qkbddriverinterface_p.h b/qmake/include/private/qkbddriverinterface_p.h index efc7ded..fe13487 100644 --- a/qmake/include/private/qkbddriverinterface_p.h +++ b/qmake/include/private/qkbddriverinterface_p.h @@ -27,14 +27,26 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QKBDDRIVERINTERFACE_H -#define QKBDDRIVERINTERFACE_H +#ifndef QKBDDRIVERINTERFACE_P_H +#define QKBDDRIVERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// #ifndef QT_H #include <private/qcom_p.h> #endif // QT_H #ifndef QT_NO_COMPONENT @@ -50,7 +62,7 @@ struct Q_EXPORT QKbdDriverInterface : public QFeatureListInterface { virtual QWSKeyboardHandler* create( const QString& driver, const QString& device ) = 0; }; #endif // QT_NO_COMPONENT -#endif // QKBDDRIVERINTERFACE_H +#endif // QKBDDRIVERINTERFACE_P_H diff --git a/qmake/include/private/qlibrary_p.h b/qmake/include/private/qlibrary_p.h index c4dd565..1624ca5 100644 --- a/qmake/include/private/qlibrary_p.h +++ b/qmake/include/private/qlibrary_p.h @@ -1,12 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Definition of an internal QLibrary class ** -** Created : 2000-01-01 +** Created : 000101 ** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License @@ -52,15 +52,12 @@ #include "qlibrary.h" #ifndef QT_NO_LIBRARY #ifndef QT_H -#if defined(Q_CC_GNU) -#warning "avoid including header file \"qwindowdefs.h\" in directory 'tools'" -#endif #include "qwindowdefs.h" #endif // QT_H class QLibraryPrivate { public: diff --git a/qmake/include/private/qlock_p.h b/qmake/include/private/qlock_p.h new file mode 100644 index 0000000..5c261aa --- a/dev/null +++ b/qmake/include/private/qlock_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** $Id$ +** +** Definition of QLock class. This manages interprocess locking +** +** Created : 20000406 +** +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** +** This file is part of the kernel module of the Qt GUI Toolkit. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses for Qt/Embedded may use this file in accordance with the +** Qt Embedded Commercial License Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef QLOCK_P_H +#define QLOCK_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// + +#ifndef QT_H +#include <qstring.h> +#endif // QT_H + +class QLockData; + +class QLock +{ +public: + QLock( const QString &filename, char id, bool create = FALSE ); + ~QLock(); + + enum Type { Read, Write }; + + bool isValid() const; + void lock( Type type ); + void unlock(); + bool locked() const; + +private: + Type type; + QLockData *data; +}; + + +// Nice class for ensuring the lock is released. +// Just create one on the stack and the lock is automatically released +// when QLockHolder is destructed. +class QLockHolder +{ +public: + QLockHolder( QLock *l, QLock::Type type ) : qlock(l) { + qlock->lock( type ); + } + ~QLockHolder() { if ( locked() ) qlock->unlock(); } + + void lock( QLock::Type type ) { qlock->lock( type ); } + void unlock() { qlock->unlock(); } + bool locked() const { return qlock->locked(); } + +private: + QLock *qlock; +}; + +#endif + diff --git a/qmake/include/private/qmousedriverinterface_p.h b/qmake/include/private/qmousedriverinterface_p.h index fd76308..42a2e3e 100644 --- a/qmake/include/private/qmousedriverinterface_p.h +++ b/qmake/include/private/qmousedriverinterface_p.h @@ -27,14 +27,26 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QMOUSEDRIVERINTERFACE_H -#define QMOUSEDRIVERINTERFACE_H +#ifndef QMOUSEDRIVERINTERFACE_P_H +#define QMOUSEDRIVERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// #ifndef QT_H #include <private/qcom_p.h> #endif // QT_H #ifndef QT_NO_COMPONENT @@ -50,7 +62,7 @@ struct Q_EXPORT QMouseDriverInterface : public QFeatureListInterface { virtual QWSMouseHandler* create( const QString& driver, const QString &device ) = 0; }; #endif // QT_NO_COMPONENT -#endif // QMOUSEDRIVERINTERFACE_H +#endif // QMOUSEDRIVERINTERFACE_P_H diff --git a/qmake/include/private/qmutexpool_p.h b/qmake/include/private/qmutexpool_p.h index 3d9fef7..fb84157 100644 --- a/qmake/include/private/qmutexpool_p.h +++ b/qmake/include/private/qmutexpool_p.h @@ -1,8 +1,43 @@ -#ifndef QMUTEXPOOL_H -#define QMUTEXPOOL_H +/**************************************************************************** +** $Id$ +** +** ... +** +** Copyright (C) 2002 Trolltech AS. All rights reserved. +** +** This file is part of the tools module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef QMUTEXPOOL_P_H +#define QMUTEXPOOL_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience @@ -25,15 +60,16 @@ public: ~QMutexPool(); QMutex *get( void *address ); private: QMutex mutex; - QMemArray<QMutex*> mutexes; + QMutex **mutexes; + int count; bool recurs; }; extern QMutexPool *qt_global_mutexpool; #endif // QT_THREAD_SUPPORT -#endif // QMUTEXPOOL_H +#endif // QMUTEXPOOL_P_H diff --git a/qmake/include/private/qpluginmanager_p.h b/qmake/include/private/qpluginmanager_p.h index 4b64ba0..a8da10e 100644 --- a/qmake/include/private/qpluginmanager_p.h +++ b/qmake/include/private/qpluginmanager_p.h @@ -1,12 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Definition of QPluginManager class ** -** Created : 2000-01-01 +** Created : 000101 ** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License @@ -32,18 +32,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QPLUGINMANAGER_H -#define QPLUGINMANAGER_H - -#ifndef QT_H -#include "qgpluginmanager_p.h" -#endif // QT_H +#ifndef QPLUGINMANAGER_P_H +#define QPLUGINMANAGER_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience @@ -51,12 +47,16 @@ // version to version without notice, or even be removed. // // We mean it. // // +#ifndef QT_H +#include "qgpluginmanager_p.h" +#endif // QT_H + #ifndef QT_NO_COMPONENT template<class Type> class QPluginManager : public QGPluginManager { public: @@ -67,7 +67,7 @@ public: return queryUnknownInterface( feature, (QUnknownInterface**)iface ); } }; #endif //QT_NO_COMPONENT -#endif //QPLUGINMANAGER_H +#endif //QPLUGINMANAGER_P_H diff --git a/qmake/include/private/qpsprinter_p.h b/qmake/include/private/qpsprinter_p.h index 27a4968..692cb44 100644 --- a/qmake/include/private/qpsprinter_p.h +++ b/qmake/include/private/qpsprinter_p.h @@ -3,13 +3,13 @@ ** ** Definition of internal QPSPrinter class. ** QPSPrinter implements PostScript (tm) output via QPrinter. ** ** Created : 940927 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -58,13 +58,13 @@ #include "qprinter.h" #include "qtextstream.h" #endif // QT_H #ifndef QT_NO_PRINTER -struct QPSPrinterPrivate; +class QPSPrinterPrivate; class Q_EXPORT QPSPrinter : public QPaintDevice { private: // QPrinter uses these QPSPrinter( QPrinter *, int ); diff --git a/qmake/include/private/qrichtext_p.h b/qmake/include/private/qrichtext_p.h index 8e29804..9ed87cf 100644 --- a/qmake/include/private/qrichtext_p.h +++ b/qmake/include/private/qrichtext_p.h @@ -153,12 +153,14 @@ public: private: QTextStringChar &operator=( const QTextStringChar & ) { //abort(); return *this; } + QTextStringChar( const QTextStringChar & ) { + } friend class QComplexText; friend class QTextParagraph; }; #if defined(Q_TEMPLATEDLL) // MOC_SKIP_BEGIN @@ -171,14 +173,14 @@ class Q_EXPORT QTextString public: QTextString(); QTextString( const QTextString &s ); virtual ~QTextString(); - static QString toString( const QMemArray<QTextStringChar> &data ); - QString toString() const; + static QString toString( const QMemArray<QTextStringChar> &data, bool fixspaces = TRUE ); + QString toString( bool fixspaces = TRUE ) const; QTextStringChar &at( int i ) const; #if defined(Q_STRICT_INLINING_RULES) // This is for the IRIX MIPSpro o32 ABI - it fails, claiming the // implementation to be a redefinition. inline int length() const; @@ -283,14 +285,14 @@ public: void gotoLineEnd(); void gotoLineStart(); void gotoHome(); void gotoEnd(); void gotoPageUp( int visibleHeight ); void gotoPageDown( int visibleHeight ); - void gotoNextWord(); - void gotoPreviousWord(); + void gotoNextWord( bool onlySpace = FALSE ); + void gotoPreviousWord( bool onlySpace = FALSE ); void gotoWordLeft(); void gotoWordRight(); void insert( const QString &s, bool checkNewLine, QMemArray<QTextStringChar> *formatting = 0 ); void splitAndInsertEmptyParagraph( bool ind = TRUE, bool updateIds = TRUE ); bool remove(); @@ -323,13 +325,13 @@ public: private: enum Operation { EnterBegin, EnterEnd, Next, Prev, Up, Down }; void push(); void pop(); - void processNesting( Operation op ); + bool processNesting( Operation op ); void invalidateNested(); void gotoIntoNested( const QPoint &globalPos ); QTextParagraph *para; int idx, tmpIndex; int ox, oy; @@ -700,12 +702,13 @@ class QTextParagraph; #endif struct Q_EXPORT QTextDocumentSelection { QTextCursor startCursor, endCursor; bool swapped; + Q_DUMMY_COMPARISON_OPERATOR(QTextDocumentSelection) }; #if defined(Q_TEMPLATEDLL) // MOC_SKIP_BEGIN Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, QColor>; Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, bool>; @@ -836,12 +839,15 @@ public: void setPaper( QBrush *brush ) { if ( backBrush ) delete backBrush; backBrush = brush; } QBrush *paper() const { return backBrush; } void doLayout( QPainter *p, int w ); void draw( QPainter *p, const QRect& rect, const QColorGroup &cg, const QBrush *paper = 0 ); + void eraseParagraphEmptyArea( QTextParagraph *parag, QPainter *p, const QColorGroup &cg ); + bool useDoubleBuffer( QTextParagraph *parag, QPainter *p ); + void drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch, QPixmap *&doubleBuffer, const QColorGroup &cg, bool drawCursor, QTextCursor *cursor, bool resetChanged = TRUE ); QTextParagraph *draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg, bool onlyChanged = FALSE, bool drawCursor = FALSE, QTextCursor *cursor = 0, bool resetChanged = TRUE ); @@ -1064,12 +1070,13 @@ private: // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ struct Q_EXPORT QTextParagraphSelection { int start, end; + Q_DUMMY_COMPARISON_OPERATOR(QTextParagraphSelection) }; struct Q_EXPORT QTextLineStart { QTextLineStart() : y( 0 ), baseLine( 0 ), h( 0 ) #ifndef QT_NO_COMPLEXTEXT @@ -1133,29 +1140,21 @@ class Q_EXPORT QTextParagraphData public: QTextParagraphData() {} virtual ~QTextParagraphData(); virtual void join( QTextParagraphData * ); }; -class Q_EXPORT QTextParagraphPseudoDocument -{ -public: - QTextParagraphPseudoDocument(); - ~QTextParagraphPseudoDocument(); - QRect docRect; - QTextFormatter *pFormatter; - QTextCommandHistory *commandHistory; - int minw; - int wused; -}; +class QTextParagraphPseudoDocument; + +class QSyntaxHighlighter; -//nase class Q_EXPORT QTextParagraph { friend class QTextDocument; friend class QTextCursor; + friend class QSyntaxHighlighter; public: QTextParagraph( QTextDocument *d, QTextParagraph *pr = 0, QTextParagraph *nx = 0, bool updateIds = TRUE ); virtual ~QTextParagraph(); QTextString *string() const; @@ -1173,13 +1172,19 @@ public: void setListDepth( int depth ); int listDepth() const { return ldepth; } // void setFormat( QTextFormat *fm ); // QTextFormat *paragFormat() const; +#if defined(Q_STRICT_INLINING_RULES) + // This is for the IRIX MIPSpro o32 ABI - it fails, claiming the + // implementation to be a redefinition. + inline QTextDocument *document() const; +#else QTextDocument *document() const; +#endif QTextParagraphPseudoDocument *pseudoDocument() const; QRect rect() const; void setHeight( int h ) { r.setHeight( h ); } void show(); void hide(); @@ -1593,13 +1598,12 @@ public: virtual QTextFormat *format( const QFont &f, const QColor &c ); virtual void remove( QTextFormat *f ); virtual QTextFormat *createFormat( const QTextFormat &f ) { return new QTextFormat( f ); } virtual QTextFormat *createFormat( const QFont &f, const QColor &c ) { return new QTextFormat( f, c, this ); } void updateDefaultFormat( const QFont &font, const QColor &c, QStyleSheet *sheet ); - QDict<QTextFormat> dict() const { return cKey; } QPaintDevice *paintDevice() const { return paintdevice; } void setPaintDevice( QPaintDevice * ); private: void updateKeys(); @@ -1613,12 +1617,25 @@ private: QString kof, knf; int cflags; QPaintDevice *paintdevice; }; +class Q_EXPORT QTextParagraphPseudoDocument +{ +public: + QTextParagraphPseudoDocument(); + ~QTextParagraphPseudoDocument(); + QRect docRect; + QTextFormatter *pFormatter; + QTextCommandHistory *commandHistory; + int minw; + int wused; + QTextFormatCollection collection; +}; + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ inline int QTextString::length() const { return data.size(); } @@ -1825,12 +1842,18 @@ inline void QTextDocument::setFlow( QTextFlow *f ) inline void QTextDocument::takeFlow() { flow_ = 0; } +inline bool QTextDocument::useDoubleBuffer( QTextParagraph *parag, QPainter *p ) +{ + return ( !parag->document()->parent() || parag->document()->nextDoubleBuffered ) && + ( !p || !p->device() || p->device()->devType() != QInternal::Printer ); +} + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ inline QColor QTextFormat::color() const { return col; } diff --git a/qmake/include/private/qsettings_p.h b/qmake/include/private/qsettings_p.h index 18d118b..095291c 100644 --- a/qmake/include/private/qsettings_p.h +++ b/qmake/include/private/qsettings_p.h @@ -91,13 +91,13 @@ public: QString groupPrefix; bool groupDirty :1; bool modified :1; bool globalScope :1; -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) // system dependent implementations to use the // system specific setting database (ie. registry on Windows) QSettingsSysPrivate *sysd; void sysInit(); void sysClear(); diff --git a/qmake/include/private/qsharedmemory_p.h b/qmake/include/private/qsharedmemory_p.h index 4a8339d..927de89 100644 --- a/qmake/include/private/qsharedmemory_p.h +++ b/qmake/include/private/qsharedmemory_p.h @@ -2,13 +2,13 @@ ** $Id$ ** ** Includes system files for shared memory ** ** Created : 020124 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 2002 Trolltech AS. All rights reserved. ** ** This file is part of the kernel module of the Qt GUI Toolkit. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the @@ -27,24 +27,26 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ +#ifndef QSHAREDMEMORY_P_H +#define QSHAREDMEMORY_P_H + // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience // of qapplication_qws.cpp and qgfxvnc_qws.cpp. This header file may // change from version to version without notice, or even be removed. // +// We mean it. +// // - -#if !defined(QT_QSHM_H) -#define QT_QSHM_H #include <qstring.h> #if !defined (QT_QWS_NO_SHM) #include <sys/types.h> @@ -78,7 +80,8 @@ private: key_t key; int idInitted; #endif }; #endif + #endif diff --git a/qmake/include/private/qsqldriverinterface_p.h b/qmake/include/private/qsqldriverinterface_p.h index 8957b86..8a39ddf 100644 --- a/qmake/include/private/qsqldriverinterface_p.h +++ b/qmake/include/private/qsqldriverinterface_p.h @@ -1,13 +1,14 @@ /**************************************************************************** +** $Id$ ** ** Definition of QSqlDriverInterface class ** ** Created : 2000-11-03 ** -** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the sql module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -34,12 +35,24 @@ ** **********************************************************************/ #ifndef QSQLDRIVERINTERFACE_H #define QSQLDRIVERINTERFACE_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// + #ifndef QT_H #include <private/qcom_p.h> #endif // QT_H #if !defined( QT_MODULE_SQL ) || defined( QT_LICENSE_PROFESSIONAL ) #define QM_EXPORT_SQL @@ -63,7 +76,7 @@ struct QM_EXPORT_SQL QSqlDriverFactoryInterface : public QFeatureListInterface virtual QSqlDriver* create( const QString& name ) = 0; }; #endif //QT_NO_COMPONENT #endif // QT_NO_SQL -#endif // QSQLDRIVERINTERFACE_H +#endif // QSQLDRIVERINTERFACE_P_H diff --git a/qmake/include/private/qsqlextension_p.h b/qmake/include/private/qsqlextension_p.h index 597b266..3445b47 100644 --- a/qmake/include/private/qsqlextension_p.h +++ b/qmake/include/private/qsqlextension_p.h @@ -48,54 +48,81 @@ // We mean it. // // #ifndef QT_H #include "qmap.h" +#include "qvaluevector.h" #include "qstring.h" #include "qvariant.h" +#include "qsql.h" #endif // QT_H #ifndef QT_NO_SQL #if !defined( QT_MODULE_SQL ) || defined( QT_LICENSE_PROFESSIONAL ) #define QM_EXPORT_SQL +#define QM_TEMPLATE_EXTERN_SQL #else #define QM_EXPORT_SQL Q_EXPORT +#define QM_TEMPLATE_EXTERN_SQL Q_TEMPLATE_EXTERN #endif +struct Param { + Param( const QVariant& v = QVariant(), QSql::ParameterType t = QSql::In ): value( v ), typ( t ) {} + QVariant value; + QSql::ParameterType typ; + Q_DUMMY_COMPARISON_OPERATOR(Param) +}; + +struct Holder { + Holder( const QString& hldr = QString::null, int pos = -1 ): holderName( hldr ), holderPos( pos ) {} + bool operator==( const Holder& h ) const { return h.holderPos == holderPos && h.holderName == holderName; } + bool operator!=( const Holder& h ) const { return h.holderPos != holderPos || h.holderName != holderName; } + QString holderName; + int holderPos; +}; + #if defined(Q_TEMPLATEDLL) -Q_TEMPLATE_EXTERN template class QM_EXPORT_SQL QMap<QString,QVariant>; -Q_TEMPLATE_EXTERN template class QM_EXPORT_SQL QMap<int,QString>; +QM_TEMPLATE_EXTERN_SQL template class QM_EXPORT_SQL QMap<QString,Param>; +QM_TEMPLATE_EXTERN_SQL template class QM_EXPORT_SQL QMap<int,QString>; +QM_TEMPLATE_EXTERN_SQL template class QM_EXPORT_SQL QValueVector<Holder>; #endif class QM_EXPORT_SQL QSqlExtension { public: QSqlExtension(); virtual ~QSqlExtension(); virtual bool prepare( const QString& query ); virtual bool exec(); - virtual void bindValue( const QString& holder, const QVariant& value ); - virtual void bindValue( int pos, const QVariant& value ); - virtual void addBindValue( const QVariant& value ); + virtual void bindValue( const QString& holder, const QVariant& value, QSql::ParameterType = QSql::In ); + virtual void bindValue( int pos, const QVariant& value, QSql::ParameterType = QSql::In ); + virtual void addBindValue( const QVariant& value, QSql::ParameterType = QSql::In ); + virtual QVariant parameterValue( const QString& holder ); + virtual QVariant parameterValue( int pos ); void clearValues(); void clearIndex(); enum BindMethod { BindByPosition, BindByName }; BindMethod bindMethod(); BindMethod bindm; int bindCount; QMap<int, QString> index; - QMap<QString, QVariant> values; + typedef QMap<QString, Param> ValueMap; + ValueMap values; + + // convenience container for QSqlQuery + // to map holders <-> positions + typedef QValueVector<Holder> HolderVector; + HolderVector holders; }; class QM_EXPORT_SQL QSqlDriverExtension { public: QSqlDriverExtension(); virtual ~QSqlDriverExtension(); virtual bool isOpen() const = 0; }; - #endif #endif diff --git a/qmake/include/private/qstyleinterface_p.h b/qmake/include/private/qstyleinterface_p.h index 4aaedc7..24a43ad 100644 --- a/qmake/include/private/qstyleinterface_p.h +++ b/qmake/include/private/qstyleinterface_p.h @@ -30,14 +30,26 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QSTYLEINTERFACE_H -#define QSTYLEINTERFACE_H +#ifndef QSTYLEINTERFACE_P_H +#define QSTYLEINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// #ifndef QT_H #include <private/qcom_p.h> #endif // QT_H #ifndef QT_NO_STYLE @@ -55,7 +67,7 @@ struct Q_EXPORT QStyleFactoryInterface : public QFeatureListInterface virtual QStyle* create( const QString& style ) = 0; }; #endif //QT_NO_COMPONENT #endif //QT_NO_STYLE -#endif //QSTYLEINTERFACE_H +#endif //QSTYLEINTERFACE_P_H diff --git a/qmake/include/private/qsvgdevice_p.h b/qmake/include/private/qsvgdevice_p.h index c1cc389..3407705 100644 --- a/qmake/include/private/qsvgdevice_p.h +++ b/qmake/include/private/qsvgdevice_p.h @@ -1,12 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Definition of the QSvgDevice class ** -** Created : 20001024 +** Created : 001024 ** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the xml module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License @@ -32,14 +32,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** *****************************************************************************/ -#ifndef QSVGDEVICE_H -#define QSVGDEVICE_H +#ifndef QSVGDEVICE_P_H +#define QSVGDEVICE_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience @@ -128,7 +128,7 @@ inline QRect QSvgDevice::boundingRect() const { return brect; } #endif // QT_NO_SVG -#endif // QSVGDEVICE_H +#endif // QSVGDEVICE_P_H diff --git a/qmake/include/private/qtextcodecinterface_p.h b/qmake/include/private/qtextcodecinterface_p.h index d2a2cb9..76e77f7 100644 --- a/qmake/include/private/qtextcodecinterface_p.h +++ b/qmake/include/private/qtextcodecinterface_p.h @@ -33,13 +33,12 @@ ** **********************************************************************/ #ifndef QTEXTCODECINTERFACE_P_H #define QTEXTCODECINTERFACE_P_H - // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience // of qpsprinter.cpp and qprinter_x11.cpp. @@ -47,13 +46,12 @@ // or even be removed. // // We mean it. // // - #ifndef QT_H #include <private/qcom_p.h> #endif // QT_H #ifndef QT_NO_TEXTCODEC #ifndef QT_NO_COMPONENT diff --git a/qmake/include/private/qtitlebar_p.h b/qmake/include/private/qtitlebar_p.h index dabb6bf..091845f 100644 --- a/qmake/include/private/qtitlebar_p.h +++ b/qmake/include/private/qtitlebar_p.h @@ -1,12 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Definition of some Qt private functions. ** -** Created : 2000-01-01 +** Created : 000101 ** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the widgets module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License diff --git a/qmake/include/private/qucom_p.h b/qmake/include/private/qucom_p.h index d2ff48e..6b6ad40 100644 --- a/qmake/include/private/qucom_p.h +++ b/qmake/include/private/qucom_p.h @@ -32,19 +32,14 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QUCOM_H -#define QUCOM_H - -#ifndef QT_H -#include <qstring.h> -#include "quuid.h" -#endif // QT_H +#ifndef QUCOM_P_H +#define QUCOM_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience @@ -52,12 +47,17 @@ // version to version without notice, or even be removed. // // We mean it. // // +#ifndef QT_H +#include <qstring.h> +#include "quuid.h" +#endif // QT_H + #ifdef check #undef check #endif struct QUObject; struct QUInterfaceDescription; @@ -126,58 +126,58 @@ public: // scary MSVC bug makes this necessary QUType *type; // the unavoidable union union { bool b; - + char c; short s; int i; long l; - + unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul; - + float f; double d; - + char byte[16]; - + struct { char* data; unsigned long size; } bytearray; - + void* ptr; - + struct { void *ptr; bool owner; } voidstar; - + struct { char *ptr; bool owner; } charstar; struct { char *ptr; bool owner; } utf8; - + struct { char *ptr; bool owner; } local8bit; - + QUnknownInterface* iface; QDispatchInterface* idisp; - + } payload; }; // A parameter description describes one method parameters. A @@ -260,13 +260,13 @@ struct Q_EXPORT QUEnumItem // - a name/value pair { const char *key; int value; }; struct Q_EXPORT QUEnum -{ +{ const char *name; // - enumerator name unsigned int count; // - number of values const QUEnumItem *items; // - the name/value pairs bool set; // whether enum has to be treated as a set }; @@ -393,30 +393,12 @@ struct Q_EXPORT QUType_int : public QUType void clear( QUObject * ) {} int serializeTo( QUObject *, QUBuffer * ); int serializeFrom( QUObject *, QUBuffer * ); }; extern Q_EXPORT QUType_int static_QUType_int; -// {5938712A-C496-11D5-8CB2-00C0F03BC0F3} -extern Q_EXPORT const QUuid TID_QUType_uint; -struct Q_EXPORT QUType_uint : public QUType -{ - const QUuid *uuid() const; - const char *desc() const; - - void set( QUObject *, uint ); - uint &get( QUObject *o ) { return o->payload.ui; } - bool canConvertFrom( QUObject *, QUType * ); - bool canConvertTo( QUObject *, QUType * ); - bool convertFrom( QUObject *, QUType * ); - bool convertTo( QUObject *, QUType * ); - void clear( QUObject * ) {} - int serializeTo( QUObject *, QUBuffer * ); - int serializeFrom( QUObject *, QUBuffer * ); -}; -extern Q_EXPORT QUType_uint static_QUType_uint; // {2D0974E5-0BA6-4ec2-8837-C198972CB48C} extern Q_EXPORT const QUuid TID_QUType_double; struct Q_EXPORT QUType_double : public QUType { const QUuid *uuid() const; @@ -431,30 +413,12 @@ struct Q_EXPORT QUType_double : public QUType void clear( QUObject * ) {} int serializeTo( QUObject *, QUBuffer * ); int serializeFrom( QUObject *, QUBuffer * ); }; extern Q_EXPORT QUType_double static_QUType_double; -// {544C5175-6993-4486-B04D-CEC4D21BF4B9 } -extern Q_EXPORT const QUuid TID_QUType_float; -struct Q_EXPORT QUType_float : public QUType -{ - const QUuid *uuid() const; - const char *desc() const; - - void set( QUObject *, float ); - float &get( QUObject *o ) { return o->payload.f; } - bool canConvertFrom( QUObject *, QUType * ); - bool canConvertTo( QUObject *, QUType * ); - bool convertFrom( QUObject *, QUType * ); - bool convertTo( QUObject *, QUType * ); - void clear( QUObject * ) {} - int serializeTo( QUObject *, QUBuffer * ); - int serializeFrom( QUObject *, QUBuffer * ); -}; -extern Q_EXPORT QUType_float static_QUType_float; // {EFCDD1D4-77A3-4b8e-8D46-DC14B8D393E9} extern Q_EXPORT const QUuid TID_QUType_charstar; struct Q_EXPORT QUType_charstar : public QUType { const QUuid *uuid() const; @@ -493,7 +457,7 @@ struct Q_EXPORT QUType_QString : public QUType int serializeFrom( QUObject *, QUBuffer * ); }; extern Q_EXPORT QUType_QString static_QUType_QString; -#endif // QUCOM_H +#endif // QUCOM_P_H diff --git a/qmake/include/private/qucomextra_p.h b/qmake/include/private/qucomextra_p.h index 3de6104..fe39692 100644 --- a/qmake/include/private/qucomextra_p.h +++ b/qmake/include/private/qucomextra_p.h @@ -32,14 +32,26 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QUCOMEXTRA_H -#define QUCOMEXTRA_H +#ifndef QUCOMEXTRA_P_H +#define QUCOMEXTRA_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// #ifndef QT_H #include <private/qucom_p.h> #endif // QT_H @@ -86,8 +98,8 @@ struct Q_EXPORT QUType_varptr : public QUType int serializeTo( QUObject *, QUBuffer * ); int serializeFrom( QUObject *, QUBuffer * ); }; extern Q_EXPORT QUType_varptr static_QUType_varptr; -#endif // QUCOMEXTRA_H +#endif // QUCOMEXTRA_P_H diff --git a/qmake/include/private/qwidgetinterface_p.h b/qmake/include/private/qwidgetinterface_p.h index 5b5776b..78e9aad 100644 --- a/qmake/include/private/qwidgetinterface_p.h +++ b/qmake/include/private/qwidgetinterface_p.h @@ -1,36 +1,43 @@ - /********************************************************************** -** Copyright (C) 2000-2001 Trolltech AS. All rights reserved. +/**************************************************************************** +** $Id$ ** -** This file is part of Qt Designer. +** ... +** +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QWIDGETINTERFACE_H -#define QWIDGETINTERFACE_H - - -#ifndef QT_H -#include <private/qcom_p.h> -#include <qiconset.h> -#endif // QT_H - -#ifndef QT_NO_WIDGETPLUGIN +#ifndef QWIDGETINTERFACE_P_H +#define QWIDGETINTERFACE_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience @@ -38,12 +45,19 @@ // version to version without notice, or even be removed. // // We mean it. // // +#ifndef QT_H +#include <private/qcom_p.h> +#include <qiconset.h> +#endif // QT_H + +#ifndef QT_NO_WIDGETPLUGIN + class QWidget; // {55184143-f18f-42c0-a8eb-71c01516019a} #ifndef IID_QWidgetFactory #define IID_QWidgetFactory QUuid( 0x55184143, 0xf18f, 0x42c0, 0xa8, 0xeb, 0x71, 0xc0, 0x15, 0x16, 0x1, 0x9a ) #endif @@ -89,23 +103,38 @@ public: /*! In the implementation return TRUE here, of the \a widget should be able to contain other widget in the Qt Designer, else FALSE. */ virtual bool isContainer( const QString &widget ) const = 0; }; -#if CONTAINER_CUSTOM_WIDGETS +#ifdef QT_CONTAINER_CUSTOM_WIDGETS // {15976628-e3c3-47f4-b525-d124a3caf30e} #ifndef IID_QWidgetContainer #define IID_QWidgetContainer QUuid( 0x15976628, 0xe3c3, 0x47f4, 0xb5, 0x25, 0xd1, 0x24, 0xa3, 0xca, 0xf3, 0x0e ) #endif struct QWidgetContainerInterfacePrivate : public QUnknownInterface { public: - virtual QWidget *containerOfWidget( QWidget *widget ) const = 0; - virtual QWidgetList containersOf( QWidget *widget ) const = 0; - virtual bool isPassiveInteractor( QWidget *widget ) const = 0; + virtual QWidget *containerOfWidget( const QString &f, QWidget *container ) const = 0; + virtual bool isPassiveInteractor( const QString &f, QWidget *container ) const = 0; + + virtual bool supportsPages( const QString &f ) const = 0; + + virtual QWidget *addPage( const QString &f, QWidget *container, + const QString &name, int index ) const = 0; + virtual void insertPage( const QString &f, QWidget *container, + const QString &name, int index, QWidget *page ) const = 0; + virtual void removePage( const QString &f, QWidget *container, int index ) const = 0; + virtual void movePage( const QString &f, QWidget *container, int fromIndex, int toIndex ) const = 0; + virtual int count( const QString &key, QWidget *container ) const = 0; + virtual int currentIndex( const QString &key, QWidget *container ) const = 0; + virtual QString pageLabel( const QString &key, QWidget *container, int index ) const = 0; + virtual QWidget *page( const QString &key, QWidget *container, int index ) const = 0; + virtual void renamePage( const QString &key, QWidget *container, + int index, const QString &newName ) const = 0; + virtual QWidgetList pages( const QString &f, QWidget *container ) const = 0; }; #endif #endif // QT_NO_WIDGETPLUGIN -#endif // QWIDGETINTERFACE_H +#endif // QWIDGETINTERFACE_P_H diff --git a/qmake/include/private/qwidgetresizehandler_p.h b/qmake/include/private/qwidgetresizehandler_p.h index ca229db..9297832 100644 --- a/qmake/include/private/qwidgetresizehandler_p.h +++ b/qmake/include/private/qwidgetresizehandler_p.h @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of the QWidgetResizeHandler class ** ** Created : 001010 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the workspace module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -32,14 +32,26 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef QWIDGETRESIZEHANDLER_H -#define QWIDGETRESIZEHANDLER_H +#ifndef QWIDGETRESIZEHANDLER_P_H +#define QWIDGETRESIZEHANDLER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// #ifndef QT_H #include "qobject.h" #endif // QT_H #ifndef QT_NO_RESIZEHANDLER class QMouseEvent; diff --git a/qmake/include/qasciidict.h b/qmake/include/qasciidict.h index 8f344cd..ecd9c9f 100644 --- a/qmake/include/qasciidict.h +++ b/qmake/include/qasciidict.h @@ -112,7 +112,11 @@ public: const char *currentKey() const { return QGDictIterator::getKeyAscii(); } type *operator()() { return (type *)QGDictIterator::operator()(); } type *operator++() { return (type *)QGDictIterator::operator++(); } type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);} }; +#ifdef QT_QWINEXPORT +#define Q_DEFINED_QASCIIDICT +#include "qwinexport.h" +#endif /* QT_QWINEXPORT */ #endif // QASCIIDICT_H diff --git a/qmake/include/qcstring.h b/qmake/include/qcstring.h index 004bb3b..6b7352a 100644 --- a/qmake/include/qcstring.h +++ b/qmake/include/qcstring.h @@ -98,15 +98,17 @@ Q_EXPORT inline int cstrncmp( const char *str1, const char *str2, uint len ) Q_EXPORT Q_UINT16 qChecksum( const char *s, uint len ); /***************************************************************************** QByteArray class *****************************************************************************/ +#ifndef QT_QWINEXPORT #if defined(Q_TEMPLATEDLL) Q_TEMPLATE_EXTERN template class Q_EXPORT QMemArray<char>; #endif +#endif /* QT_QWINEXPORT */ #if defined(Q_QDOC) /* We want qdoc to document QByteArray as a real class that inherits QMemArray<char> and that is inherited by QBitArray. */ @@ -229,12 +231,14 @@ public: bool setExpand( uint index, char c ); operator const char *() const; QCString &operator+=( const char *str ); QCString &operator+=( char c ); +private: + int find( const char *str, int index, bool cs, uint l ) const; }; /***************************************************************************** QCString stream functions *****************************************************************************/ @@ -385,7 +389,10 @@ Q_EXPORT inline const QCString operator+( char c1, const QCString &s2 ) QCString tmp; tmp += c1; tmp += s2; return tmp; } +#ifdef QT_QWINEXPORT +#include <qwinexport.h> +#endif /* QT_QWINEXPORT */ #endif // QCSTRING_H diff --git a/qmake/include/qdict.h b/qmake/include/qdict.h index 04ae7bf..d8943ad 100644 --- a/qmake/include/qdict.h +++ b/qmake/include/qdict.h @@ -112,7 +112,11 @@ public: QString currentKey() const{ return QGDictIterator::getKeyString(); } type *operator()() { return (type *)QGDictIterator::operator()(); } type *operator++() { return (type *)QGDictIterator::operator++(); } type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j); } }; +#ifdef QT_QWINEXPORT +#define Q_DEFINED_QDICT +#include "qwinexport.h" +#endif /* QT_QWINEXPORT */ #endif // QDICT_H diff --git a/qmake/include/qdir.h b/qmake/include/qdir.h index 6e9f1ab..4b08b79 100644 --- a/qmake/include/qdir.h +++ b/qmake/include/qdir.h @@ -175,23 +175,24 @@ public: static QString rootDirPath(); static bool match( const QStringList &filters, const QString &fileName ); static bool match( const QString &filter, const QString &fileName ); static QString cleanDirPath( const QString &dirPath ); static bool isRelativePath( const QString &path ); + void refresh() const; private: #ifdef Q_OS_MAC typedef struct FSSpec FSSpec; static FSSpec *make_spec(const QString &); #endif void init(); virtual bool readDirEntries( const QString &nameFilter, int FilterSpec, int SortSpec ); - static void slashify ( QString &); + static void slashify( QString & ); QString dPath; QStringList *fList; QFileInfoList *fiList; QString nameFilt; FilterSpec filtS; diff --git a/qmake/include/qfeatures.h b/qmake/include/qfeatures.h index 57502f9..270a6de 100644 --- a/qmake/include/qfeatures.h +++ b/qmake/include/qfeatures.h @@ -71,13 +71,13 @@ // 24-bit color //#define QT_NO_QWS_DEPTH_24 // 32-bit color //#define QT_NO_QWS_DEPTH_32 -// 4-bit greyscale +// 4-bit grayscale //#define QT_NO_QWS_DEPTH_4 // 8-bit color //#define QT_NO_QWS_DEPTH_8 // 8-bit grayscale diff --git a/qmake/include/qgarray.h b/qmake/include/qgarray.h index 12edea6..40720a6 100644 --- a/qmake/include/qgarray.h +++ b/qmake/include/qgarray.h @@ -46,17 +46,25 @@ class Q_EXPORT QGArray // generic array { friend class QBuffer; public: //### DO NOT USE THIS. IT IS PUBLIC BUT DO NOT USE IT IN NEW CODE. struct array_data : public QShared { // shared array - array_data() { data=0; len=0; } + array_data():data(0),len(0) +#ifdef QT_QGARRAY_SPEED_OPTIM + ,maxl(0) +#endif + {} char *data; // actual array data uint len; +#ifdef QT_QGARRAY_SPEED_OPTIM + uint maxl; +#endif }; QGArray(); + enum Optimization { MemOptim, SpeedOptim }; protected: QGArray( int, int ); // dummy; does not alloc QGArray( int size ); // allocate 'size' bytes QGArray( const QGArray &a ); // shallow copy virtual ~QGArray(); @@ -67,12 +75,13 @@ protected: // ### Qt 4.0: maybe provide two versions of data(), at(), etc. char *data() const { return shd->data; } uint nrefs() const { return shd->count; } uint size() const { return shd->len; } bool isEqual( const QGArray &a ) const; + bool resize( uint newsize, Optimization optim ); bool resize( uint newsize ); bool fill( const char *d, int len, uint sz ); QGArray &assign( const QGArray &a ); QGArray &assign( const char *d, uint len ); @@ -85,13 +94,13 @@ protected: QGArray &setRawData( const char *d, uint len ); void resetRawData( const char *d, uint len ); int find( const char *d, uint index, uint sz ) const; int contains( const char *d, uint sz ) const; - + void sort( uint sz ); int bsearch( const char *d, uint sz ) const; char *at( uint index ) const; bool setExpand( uint index, const char *d, uint sz ); diff --git a/qmake/include/qglobal.h b/qmake/include/qglobal.h index 13cff64..d212bff 100644 --- a/qmake/include/qglobal.h +++ b/qmake/include/qglobal.h @@ -35,17 +35,17 @@ ** **********************************************************************/ #ifndef QGLOBAL_H #define QGLOBAL_H -#define QT_VERSION_STR "3.1.0-b2" +#define QT_VERSION_STR "3.1.2" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x030100 +#define QT_VERSION 0x030102 /* The operating system, must be one of: (Q_OS_x) MACX - Mac OS X MAC9 - Mac OS 9 @@ -138,18 +138,18 @@ #elif defined(__QNXNTO__) # define Q_OS_QNX6 #elif defined(__QNX__) # define Q_OS_QNX #elif defined(_SEQUENT_) # define Q_OS_DYNIX -#elif defined(_SCO_DS) /* SCO OpenServer 5 */ +#elif defined(_SCO_DS) /* SCO OpenServer 5 + GCC */ # define Q_OS_SCO -#elif defined(__UNIXWARE__) /* UnixWare 7 + GCC, Open UNIX 8 + GCC */ +#elif defined(__USLC__) /* all SCO platforms + UDK or OUDK */ # define Q_OS_UNIXWARE # define Q_OS_UNIXWARE7 -#elif defined(__USLC__) /* UnixWare 7 + UDK, Open UNIX 8 + OUDK */ +#elif defined(__svr4__) && defined(i386) /* Open UNIX 8 + GCC */ # define Q_OS_UNIXWARE # define Q_OS_UNIXWARE7 #else # error "Qt has not been ported to this OS - talk to qt-bugs@trolltech.com" #endif @@ -222,13 +222,15 @@ /* proper support of bool for _MSC_VER >= 1100 */ # define Q_CANNOT_DELETE_CONSTANT # define Q_INLINE_TEMPLATES inline /* Visual C++.Net issues for _MSC_VER >= 1300 */ # if _MSC_VER >= 1300 # define Q_CC_MSVC_NET -# define Q_TYPENAME +# if _MSC_VER < 1310 +# define Q_TYPENAME +# endif # endif # define Q_NO_USING_KEYWORD /* ### check "using" status */ #elif defined(__BORLANDC__) || defined(__TURBOC__) # define Q_CC_BOR # if __BORLANDC__ < 0x502 @@ -268,12 +270,16 @@ # define Q_FULL_TEMPLATE_INSTANTIATION # endif /* GCC 2.95 knows "using" but does not support it correctly */ # if __GNUC__ == 2 && __GNUC_MINOR__ <= 95 # define Q_NO_USING_KEYWORD # endif +/* GCC 3.1 and GCC 3.2 wrongly define _SB_CTYPE_MACROS on HP-UX */ +# if defined(Q_OS_HPUX) && __GNUC__ == 3 && __GNUC_MINOR__ >= 1 +# define Q_WRONG_SB_CTYPE_MACROS +# endif # if (defined(__arm__) || defined(__ARMEL__)) && !defined(QT_MOC_CPP) # define Q_PACKED __attribute__ ((packed)) # endif # if !defined(__EXCEPTIONS) # define Q_NO_EXCEPTIONS # endif @@ -387,22 +393,25 @@ # elif defined(__ghs) # define Q_CC_GHS /* The UnixWare 7 UDK compiler is based on EDG and does define __EDG__ */ # elif defined(__USLC__) && defined(__SCO_VERSION__) # define Q_CC_USLC +/* The latest UDK 7.1.1b does not need this, but previous versions do */ +# if !defined(__SCO_VERSION__) || (__SCO_VERSION__ < 302200010) +# define Q_INLINE_TEMPLATES inline +# endif # define Q_NO_USING_KEYWORD /* ### check "using" status */ /* Never tested! */ # elif defined(CENTERLINE_CLPP) || defined(OBJECTCENTER) # define Q_CC_OC # define Q_NO_USING_KEYWORD -/* CDS++ is not documented to define __EDG__ or __EDG in the Reliant - documentation but we suppose it does, in any case it does follow - conventions like _BOOL */ +/* CDS++ defines __EDG__ although this is not documented in the Reliant + documentation. It also follows conventions like _BOOL and this documented */ # elif defined(sinix) # define Q_CC_CDS # define Q_NO_USING_KEYWORD # if defined(__cplusplus) && (__cplusplus < 2) /* Cfront C++ mode */ # define Q_NO_EXCEPTIONS # endif @@ -412,25 +421,29 @@ # elif defined(__sgi) # define Q_CC_MIPS # if defined(_MIPS_SIM) && (_MIPS_SIM == _ABIO32) /* o32 ABI */ # define Q_TYPENAME # define Q_BROKEN_TEMPLATE_SPECIALIZATION # define Q_STRICT_INLINING_RULES +# define Q_NO_EXPLICIT_KEYWORD +# define Q_INLINE_TEMPLATES inline # elif defined(_COMPILER_VERSION) && (_COMPILER_VERSION < 730) /* 7.2 */ # define Q_TYPENAME # define Q_BROKEN_TEMPLATE_SPECIALIZATION # endif # define Q_NO_USING_KEYWORD /* ### check "using" status */ # endif /* The older UnixWare 2.X compiler? */ -#elif defined(__USLC__) && !defined(__SCO_VERSION__) +#elif defined(__USLC__) # define Q_CC_USLC +# define Q_TYPENAME # define Q_NO_BOOL_TYPE # define Q_NO_EXPLICIT_KEYWORD # define Q_NO_USING_KEYWORD +# define Q_INLINE_TEMPLATES inline /* Never tested! */ #elif defined(__HIGHC__) # define Q_CC_HIGHC #elif defined(__SUNPRO_CC) @@ -451,12 +464,22 @@ # else # define Q_NO_BOOL_TYPE # define Q_NO_EXPLICIT_KEYWORD # define Q_NO_USING_KEYWORD # endif +/* CDS++ does not seem to define __EDG__ or __EDG according to Reliant + documentation but nevertheless uses EDG conventions like _BOOL */ +#elif defined(sinix) +# define Q_CC_EDG +# define Q_CC_CDS +# if !defined(_BOOL) +# define Q_NO_BOOL_TYPE +# endif +# define Q_BROKEN_TEMPLATE_SPECIALIZATION + #elif defined(Q_OS_HPUX) /* __HP_aCC was not defined in first aCC releases */ # if defined(__HP_aCC) || __cplusplus >= 199707L # define Q_CC_HPACC # else # define Q_CC_HP @@ -503,12 +526,13 @@ #elif defined(Q_OS_OS2) # define Q_WS_PM # error "Qt does not work with OS/2 Presentation Manager or Workplace Shell" #elif defined(Q_OS_UNIX) # if defined(QWS) # define Q_WS_QWS +# define QT_NO_QWS_IM # elif defined(Q_OS_MACX) # define Q_WS_MACX # else # define Q_WS_X11 # endif #endif @@ -742,19 +766,24 @@ class QDataStream; # endif # ifndef QMAC_QMENUBAR_NO_EVENT # define QMAC_QMENUBAR_NO_EVENT # endif #endif +#if !defined(Q_WS_QWS) && !defined(QT_NO_COP) +# define QT_NO_COP +#endif + #ifndef QT_H #include <qfeatures.h> #endif // QT_H // // Create Qt DLL if QT_DLL is defined (Windows only) +// or QT_SHARED is defined (Kylix only) // #if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) # if defined(QT_NODLL) # undef QT_MAKEDLL # undef QT_DLL @@ -767,19 +796,30 @@ class QDataStream; # define Q_TEMPLATE_EXTERN # undef Q_DISABLE_COPY /* avoid unresolved externals */ # elif defined(QT_DLL) /* use a Qt DLL library */ # define Q_EXPORT __declspec(dllimport) # define Q_TEMPLATEDLL # ifndef Q_TEMPLATE_EXTERN -# if defined(Q_CC_MSVC) -# define Q_TEMPLATE_EXTERN /*extern*/ //### too many warnings, even though disabled +# if defined(Q_CC_MSVC_NET) +# define Q_TEMPLATE_EXTERN extern # else # define Q_TEMPLATE_EXTERN # endif # endif -# undef Q_DISABLE_COPY /* avoid unresolved externals */ +# undef Q_DISABLE_COPY /* avoid unresolved externals */ +# endif +#elif defined(Q_OS_LINUX) && defined(Q_CC_BOR) +# if defined(QT_SHARED) /* create a Qt shared library */ +# define Q_EXPORT __declspec(dllexport) +# define Q_TEMPLATEDLL +# define Q_TEMPLATE_EXTERN +# undef Q_DISABLE_COPY /* avoid unresolved externals */ +# else +# define Q_TEMPLATEDLL +# define Q_TEMPLATE_EXTERN +# undef Q_DISABLE_COPY /* avoid unresolved externals */ # endif #else # undef QT_MAKEDLL /* ignore these for other platforms */ # undef QT_DLL #endif @@ -800,13 +840,15 @@ extern Q_EXPORT bool qt_winunicode; // // System information // Q_EXPORT const char *qVersion(); Q_EXPORT bool qSysInfo( int *wordSize, bool *bigEndian ); -#if defined(Q_WS_WIN) +#if defined(Q_OS_MAC) +int qMacVersion(); +#elif defined(Q_WS_WIN) Q_EXPORT int qWinVersion(); #if defined(UNICODE) #define QT_WA( uni, ansi ) if ( qt_winunicode ) { uni } else { ansi } #define QT_WA_INLINE( uni, ansi ) ( qt_winunicode ? uni : ansi ) #else #define QT_WA( uni, ansi ) ansi @@ -966,12 +1008,28 @@ Q_EXPORT const char *qInstallPathLibs(); Q_EXPORT const char *qInstallPathBins(); Q_EXPORT const char *qInstallPathPlugins(); Q_EXPORT const char *qInstallPathData(); #endif // __cplusplus +// compilers which follow outdated template instantiation rules +// require a class to have a comparison operator to exist when +// a QValueList of this type is instantiated. It's not actually +// used in the list, though. Hence the dummy implementation. +// Just in case other code relies on it we better trigger a warning +// mandating a real implementation. +#ifdef Q_FULL_TEMPLATE_INSTANTIATION +# define Q_DUMMY_COMPARISON_OPERATOR(C) \ + bool operator==( const C& ) const { \ + qWarning( #C"::operator==( const "#C"& ) got called." ); \ + return FALSE; \ + } +#else +# define Q_DUMMY_COMPARISON_OPERATOR(C) +#endif + #endif // QGLOBAL_H // // Avoid some particularly useless warnings from some stupid compilers. // To get ALL C++ compiler warnings, define QT_CC_WARNINGS or comment out // the line "#define QT_NO_WARNINGS" @@ -989,12 +1047,13 @@ Q_EXPORT const char *qInstallPathData(); # pragma warning(disable: 4097) // typedef-name 'identifier1' used as synonym for class-name 'identifier2' # pragma warning(disable: 4706) // assignment within conditional expression # pragma warning(disable: 4786) // truncating debug info after 255 characters # pragma warning(disable: 4660) // template-class specialization 'identifier' is already instantiated # pragma warning(disable: 4355) // 'this' : used in base member initializer list # pragma warning(disable: 4231) // nonstandard extension used : 'extern' before template explicit instantiation +# pragma warning(disable: 4710) // function not inlined # elif defined(Q_CC_BOR) # pragma option -w-inl # pragma option -w-aus # pragma warn -inl # pragma warn -pia # pragma warn -ccc diff --git a/qmake/include/qintdict.h b/qmake/include/qintdict.h index b4cb223..0299879 100644 --- a/qmake/include/qintdict.h +++ b/qmake/include/qintdict.h @@ -108,7 +108,11 @@ public: long currentKey() const { return QGDictIterator::getKeyInt(); } type *operator()() { return (type *)QGDictIterator::operator()(); } type *operator++() { return (type *)QGDictIterator::operator++(); } type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);} }; +#ifdef QT_QWINEXPORT +#define Q_DEFINED_QINTDICT +#include "qwinexport.h" +#endif /* QT_QWINEXPORT */ #endif // QINTDICT_H diff --git a/qmake/include/qmap.h b/qmake/include/qmap.h index 269bd6b..4bc0a2f 100644 --- a/qmake/include/qmap.h +++ b/qmake/include/qmap.h @@ -877,7 +877,11 @@ Q_INLINE_TEMPLATES QDataStream& operator<<( QDataStream& s, const QMap<Key,T>& m for( ; it != m.end(); ++it ) s << it.key() << it.data(); return s; } #endif +#ifdef QT_QWINEXPORT +#define Q_DEFINED_QMAP +#include "qwinexport.h" +#endif /* QT_QWINEXPORT */ #endif // QMAP_H diff --git a/qmake/include/qmemarray.h b/qmake/include/qmemarray.h index a5baf99..267670d 100644 --- a/qmake/include/qmemarray.h +++ b/qmake/include/qmemarray.h @@ -40,13 +40,13 @@ #ifndef QT_H #include "qgarray.h" #endif // QT_H -template<class type> +template<class type> class QMemArray : public QGArray { public: typedef type* Iterator; typedef const type* ConstIterator; typedef type ValueType; @@ -65,12 +65,13 @@ public: uint nrefs() const { return QGArray::nrefs(); } uint size() const { return QGArray::size()/sizeof(type); } uint count() const { return size(); } bool isEmpty() const { return QGArray::size() == 0; } bool isNull() const { return QGArray::data() == 0; } bool resize( uint size ) { return QGArray::resize(size*sizeof(type)); } + bool resize( uint size, Optimization optim ) { return QGArray::resize(size*sizeof(type), optim); } bool truncate( uint pos ) { return QGArray::resize(pos*sizeof(type)); } bool fill( const type &d, int size = -1 ) { return QGArray::fill((char*)&d,size,sizeof(type) ); } void detach() { QGArray::detach(); } QMemArray<type> copy() const { QMemArray<type> tmp; return tmp.duplicate(*this); } @@ -105,18 +106,24 @@ public: Iterator begin() { return data(); } Iterator end() { return data() + size(); } ConstIterator begin() const { return data(); } ConstIterator end() const { return data() + size(); } }; +#ifndef QT_QWINEXPORT #if defined(Q_TEMPLATEDLL) // MOC_SKIP_BEGIN Q_TEMPLATE_EXTERN template class Q_EXPORT QMemArray<int>; Q_TEMPLATE_EXTERN template class Q_EXPORT QMemArray<bool>; // MOC_SKIP_END #endif +#endif /* QT_QWINEXPORT */ #ifndef QT_NO_COMPAT #define QArray QMemArray #endif +#ifdef QT_QWINEXPORT +#define Q_DEFINED_QMEMARRAY +#include <qwinexport.h> +#endif /* QT_QWINEXPORT */ #endif // QARRAY_H diff --git a/qmake/include/qptrlist.h b/qmake/include/qptrlist.h index 53fb605..17b5ee9 100644 --- a/qmake/include/qptrlist.h +++ b/qmake/include/qptrlist.h @@ -1,13 +1,11 @@ /**************************************************************************** ** $Id$ ** ** Definition of QPtrList template/macro class ** -** Created : -** ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file @@ -154,7 +152,11 @@ public: #ifndef QT_NO_COMPAT #define QList QPtrList #define QListIterator QPtrListIterator #endif +#ifdef QT_QWINEXPORT +#define Q_DEFINED_QPTRLIST +#include "qwinexport.h" +#endif /* QT_QWINEXPORT */ #endif // QPTRLIST_H diff --git a/qmake/include/qptrvector.h b/qmake/include/qptrvector.h index f6d9623..49b40b7 100644 --- a/qmake/include/qptrvector.h +++ b/qmake/include/qptrvector.h @@ -107,7 +107,11 @@ template<class type> inline void QPtrVector<type>::deleteItem( QPtrCollection::I } #ifndef QT_NO_COMPAT #define QVector QPtrVector #endif +#ifdef QT_QWINEXPORT +#define Q_DEFINED_QPTRVECTOR +#include "qwinexport.h" +#endif /* QT_QWINEXPORT */ #endif // QVECTOR_H diff --git a/qmake/include/qregexp.h b/qmake/include/qregexp.h index 7bb777a..90f54bd 100644 --- a/qmake/include/qregexp.h +++ b/qmake/include/qregexp.h @@ -77,13 +77,13 @@ public: bool exactMatch( const QString& str ) const; #ifndef QT_NO_COMPAT int match( const QString& str, int index = 0, int *len = 0, bool indexIsStart = TRUE ) const; #endif -#if defined(qdoc) +#if defined(Q_QDOC) int search( const QString& str, int offset = 0, CaretMode caretMode = CaretAtZero ) const; int searchRev( const QString& str, int offset = -1, CaretMode caretMode = CaretAtZero ) const; #else // ### Qt 4.0: reduce these four to two functions diff --git a/qmake/include/qstring.h b/qmake/include/qstring.h index 2a87a5a..c1d6740 100644 --- a/qmake/include/qstring.h +++ b/qmake/include/qstring.h @@ -1,15 +1,14 @@ /**************************************************************************** ** $Id$ ** -** Definition of the QString class, and related Unicode -** functions. +** Definition of the QString class, and related Unicode functions. ** ** Created : 920609 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -40,12 +39,19 @@ #define QSTRING_H #ifndef QT_H #include "qcstring.h" #endif // QT_H +#ifndef QT_NO_STL +#include <string> +#if defined(Q_WRONG_SB_CTYPE_MACROS) && defined(_SB_CTYPE_MACROS) +#undef _SB_CTYPE_MACROS +#endif +#endif + /***************************************************************************** QString class *****************************************************************************/ class QRegExp; @@ -333,40 +339,40 @@ inline bool operator>( QChar c, char ch ) { return !(ch>=c); } inline bool operator>( char ch, QChar c ) { return !(c>=ch); } inline bool operator>( QChar c1, QChar c2 ) { return !(c2>=c1); } // internal struct Q_EXPORT QStringData : public QShared { QStringData() : - QShared(), unicode(0), ascii(0), len(0), simpletext(1), maxl(0), dirty(0) { ref(); } + QShared(), unicode(0), ascii(0), len(0), issimpletext(TRUE), maxl(0), islatin1(FALSE) { ref(); } QStringData(QChar *u, uint l, uint m) : - QShared(), unicode(u), ascii(0), len(l), simpletext(1), maxl(m), dirty(1) { } + QShared(), unicode(u), ascii(0), len(l), issimpletext(FALSE), maxl(m), islatin1(FALSE) { } ~QStringData() { if ( unicode ) delete[] ((char*)unicode); if ( ascii ) delete[] ascii; } void deleteSelf(); QChar *unicode; char *ascii; void setDirty() { if ( ascii ) { delete [] ascii; ascii = 0; } - dirty = 1; + issimpletext = FALSE; } #ifdef Q_OS_MAC9 uint len; #else uint len : 30; #endif - uint simpletext : 1; + uint issimpletext : 1; #ifdef Q_OS_MAC9 uint maxl; #else uint maxl : 30; #endif - uint dirty : 1; + uint islatin1 : 1; private: #if defined(Q_DISABLE_COPY) QStringData( const QStringData& ); QStringData& operator=( const QStringData& ); #endif @@ -381,17 +387,21 @@ public: QString( const QString & ); // impl-shared copy QString( const QByteArray& ); // deep copy QString( const QChar* unicode, uint length ); // deep copy #ifndef QT_NO_CAST_ASCII QString( const char *str ); // deep copy #endif +#ifndef QT_NO_STL + QString( const std::string& ); // deep copy +#endif ~QString(); QString &operator=( const QString & ); // impl-shared copy -#ifndef QT_NO_CAST_ASCII QString &operator=( const char * ); // deep copy +#ifndef QT_NO_STL + QString &operator=( const std::string& ); // deep copy #endif QString &operator=( const QCString& ); // deep copy QString &operator=( QChar c ); QString &operator=( char c ); QT_STATIC_CONST QString null; @@ -491,19 +501,25 @@ public: QString &append( QChar ); QString &append( const QString & ); #ifndef QT_NO_CAST_ASCII QString &append( const QByteArray & ); QString &append( const char * ); #endif +#ifndef QT_NO_STL + QString &append( const std::string& ); +#endif QString &prepend( char ); QString &prepend( QChar ); QString &prepend( const QString & ); #ifndef QT_NO_CAST_ASCII QString &prepend( const QByteArray & ); QString &prepend( const char * ); #endif +#ifndef QT_NO_STL + QString &prepend( const std::string& ); +#endif QString &remove( uint index, uint len ); QString &remove( QChar c ); QString &remove( char c ) { return remove( QChar(c) ); } QString &remove( const QString & ); #ifndef QT_NO_REGEXP QString &remove( const QRegExp & ); @@ -553,12 +569,15 @@ public: QString &operator+=( const QString &str ); #ifndef QT_NO_CAST_ASCII QString &operator+=( const QByteArray &str ); QString &operator+=( const char *str ); #endif +#ifndef QT_NO_STL + QString &operator+=( const std::string& ); +#endif QString &operator+=( QChar c ); QString &operator+=( char c ); QChar at( uint i ) const { return i < d->len ? d->unicode[i] : QChar::null; } QChar operator[]( int i ) const { return at((uint)i); } @@ -573,28 +592,34 @@ public: subat( i ); d->setDirty(); return d->unicode[i]; } const QChar* unicode() const { return d->unicode; } - const char* ascii() const { return latin1(); } + const char* ascii() const; + static QString fromAscii(const char*, int len=-1); const char* latin1() const; static QString fromLatin1(const char*, int len=-1); QCString utf8() const; static QString fromUtf8(const char*, int len=-1); QCString local8Bit() const; static QString fromLocal8Bit(const char*, int len=-1); bool operator!() const; #ifndef QT_NO_ASCII_CAST - operator const char *() const { return latin1(); } + operator const char *() const { return ascii(); } #endif +#ifndef QT_NO_STL + operator std::string() const { return ascii() ? ascii() : ""; } +#endif + static QString fromUcs2( const unsigned short *ucs2 ); const unsigned short *ucs2() const; QString &setUnicode( const QChar* unicode, uint len ); QString &setUnicodeCodes( const ushort* unicode_as_ushorts, uint len ); + QString &setAscii( const char*, int len=-1 ); QString &setLatin1( const char*, int len=-1 ); int compare( const QString& s ) const; static int compare( const QString& s1, const QString& s2 ) { return s1.compare( s2 ); } @@ -606,21 +631,21 @@ public: friend Q_EXPORT QDataStream &operator>>( QDataStream &, QString & ); #endif void compose(); #ifndef QT_NO_COMPAT - const char* data() const { return latin1(); } + const char* data() const { return ascii(); } #endif bool startsWith( const QString& ) const; bool endsWith( const QString& ) const; void setLength( uint newLength ); - bool simpleText() const { if ( d->dirty ) checkSimpleText(); return (bool)d->simpletext; } + bool simpleText() const { if ( !d->issimpletext ) checkSimpleText(); return (bool)d->issimpletext; } bool isRightToLeft() const; private: QString( int size, bool /* dummy */ ); // allocate size incl. \0 @@ -628,15 +653,15 @@ private: void real_detach(); void subat( uint ); bool findArg(int& pos, int& len) const; void checkSimpleText() const; - static QChar* asciiToUnicode( const char*, uint * len, uint maxlen=(uint)-1 ); - static QChar* asciiToUnicode( const QByteArray&, uint * len ); - static char* unicodeToAscii( const QChar*, uint len ); + static QChar* latin1ToUnicode( const char*, uint * len, uint maxlen=(uint)-1 ); + static QChar* latin1ToUnicode( const QByteArray&, uint * len ); + static char* unicodeToLatin1( const QChar*, uint len ); QStringData *d; static QStringData* shared_null; static QStringData* makeSharedNull(); friend class QConstString; @@ -791,35 +816,47 @@ inline QString &QString::prepend( QChar c ) inline QString &QString::prepend( char c ) { return insert(0,c); } #ifndef QT_NO_CAST_ASCII inline QString &QString::prepend( const QByteArray & s ) -{ return insert(0,s.data()); } +{ return insert(0,QString(s)); } +#endif + +#ifndef QT_NO_STL +inline QString &QString::prepend( const std::string& s ) +{ return insert(0, s); } +#endif + +#ifndef QT_NO_CAST_ASCII +inline QString &QString::operator+=( const QByteArray &s ) +{ return operator+=(QString(s)); } #endif inline QString &QString::append( const QString & s ) { return operator+=(s); } #ifndef QT_NO_CAST_ASCII inline QString &QString::append( const QByteArray &s ) -{ return operator+=(s.data()); } +{ return operator+=(s); } inline QString &QString::append( const char * s ) { return operator+=(s); } #endif inline QString &QString::append( QChar c ) { return operator+=(c); } inline QString &QString::append( char c ) { return operator+=(c); } -#ifndef QT_NO_CAST_ASCII -inline QString &QString::operator+=( const QByteArray &s ) -{ return operator+=(s.data()); } +#ifndef QT_NO_STL +inline QString &QString::operator+=( const std::string& s ) +{ return operator+=(s.c_str()); } +inline QString &QString::append( const std::string& s ) +{ return operator+=(s); } #endif inline QString &QString::setNum( short n, int base ) { return setNum((long)n, base); } inline QString &QString::setNum( ushort n, int base ) @@ -851,16 +888,16 @@ inline int QString::find( char c, int index, bool cs ) const inline int QString::findRev( char c, int index, bool cs) const { return findRev( QChar(c), index, cs ); } #ifndef QT_NO_CAST_ASCII inline int QString::find( const char* str, int index ) const -{ return find(QString::fromLatin1(str), index); } +{ return find(QString::fromAscii(str), index); } inline int QString::findRev( const char* str, int index ) const -{ return findRev(QString::fromLatin1(str), index); } +{ return findRev(QString::fromAscii(str), index); } #endif /***************************************************************************** QString non-member operators *****************************************************************************/ @@ -894,19 +931,19 @@ Q_EXPORT inline const QString operator+( const QString &s1, const QString &s2 ) } #ifndef QT_NO_CAST_ASCII Q_EXPORT inline const QString operator+( const QString &s1, const char *s2 ) { QString tmp( s1 ); - tmp += QString::fromLatin1(s2); + tmp += QString::fromAscii(s2); return tmp; } Q_EXPORT inline const QString operator+( const char *s1, const QString &s2 ) { - QString tmp = QString::fromLatin1( s1 ); + QString tmp = QString::fromAscii( s1 ); tmp += s2; return tmp; } #endif Q_EXPORT inline const QString operator+( const QString &s1, QChar c2 ) @@ -944,7 +981,11 @@ extern Q_EXPORT QString qt_winQString(void*); extern Q_EXPORT const void* qt_winTchar(const QString& str, bool addnul); extern Q_EXPORT void* qt_winTchar_new(const QString& str); extern Q_EXPORT QCString qt_winQString2MB( const QString& s, int len=-1 ); extern Q_EXPORT QString qt_winMB2QString( const char* mb, int len=-1 ); #endif +#ifdef QT_QWINEXPORT +#define Q_DEFINED_QSTRING +#include "qwinexport.h" +#endif /* QT_QWINEXPORT */ #endif // QSTRING_H diff --git a/qmake/include/qstrlist.h b/qmake/include/qstrlist.h index 86de328..b9dd753 100644 --- a/qmake/include/qstrlist.h +++ b/qmake/include/qstrlist.h @@ -42,16 +42,18 @@ #include "qstring.h" #include "qptrlist.h" #include "qdatastream.h" #endif // QT_H +#ifndef QT_QWINEXPORT #if defined(Q_TEMPLATEDLL) Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<char>; Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrListIterator<char>; #endif +#endif /* QT_QWINEXPORT */ #if defined(Q_QDOC) class QStrListIterator : public QPtrListIterator<char> { }; #else diff --git a/qmake/include/qtextcodec.h b/qmake/include/qtextcodec.h index 149b5cb..995e434 100644 --- a/qmake/include/qtextcodec.h +++ b/qmake/include/qtextcodec.h @@ -72,12 +72,17 @@ public: static QTextCodec* codecForName(const char* hint, int accuracy=0); static QTextCodec* codecForContent(const char* chars, int len); static QTextCodec* codecForIndex(int i); static QTextCodec* codecForLocale(); static void setCodecForLocale(QTextCodec *c); + static QTextCodec* codecForTr(); + static void setCodecForTr(QTextCodec *c); + static QTextCodec* codecForCStrings(); + static void setCodecForCStrings(QTextCodec *c); + static void deleteAllCodecs(); static const char* locale(); virtual const char* name() const = 0; virtual const char* mimeName() const; @@ -85,13 +90,13 @@ public: virtual QTextDecoder* makeDecoder() const; virtual QTextEncoder* makeEncoder() const; virtual QString toUnicode(const char* chars, int len) const; virtual QCString fromUnicode(const QString& uc, int& lenInOut) const; - + QCString fromUnicode(const QString& uc) const; QString toUnicode(const QByteArray&, int len) const; QString toUnicode(const QByteArray&) const; QString toUnicode(const QCString&, int len) const; QString toUnicode(const QCString&) const; QString toUnicode(const char* chars) const; @@ -105,10 +110,19 @@ public: virtual unsigned short characterFromUnicode(const QString &str, int pos) const; protected: QTextCodec(); static int simpleHeuristicNameMatch(const char* name, const char* hint); +private: + static QTextCodec *cftr; + static QTextCodec *cfcs; friend class QFont; }; + +inline QTextCodec* QTextCodec::codecForTr() { return cftr; } +inline void QTextCodec::setCodecForTr(QTextCodec *c) { cftr = c; } +inline QTextCodec* QTextCodec::codecForCStrings() { return cfcs; } +inline void QTextCodec::setCodecForCStrings(QTextCodec *c) { cfcs = c; } + #endif // QT_NO_TEXTCODEC #endif // QTEXTCODEC_H diff --git a/qmake/include/qtl.h b/qmake/include/qtl.h index 346cecc..25631fd 100644 --- a/qmake/include/qtl.h +++ b/qmake/include/qtl.h @@ -86,12 +86,13 @@ inline BiOutputIterator qCopyBackward( BiIterator _begin, BiIterator _end, return _dest; } template <class InputIterator1, class InputIterator2> inline bool qEqual( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 ) { + // ### compare using !(*first1 == *first2) in Qt 4.0 for ( ; first1 != last1; ++first1, ++first2 ) if ( *first1 != *first2 ) return FALSE; return TRUE; } diff --git a/qmake/include/quuid.h b/qmake/include/quuid.h index 591d2f1..664c149 100644 --- a/qmake/include/quuid.h +++ b/qmake/include/quuid.h @@ -1,14 +1,14 @@ /**************************************************************************** ** $Id$ ** ** Definition of QUuid class ** -** Created: 010523 +** Created : 010523 ** -** Copyright (C) 1992-2001 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -50,13 +50,13 @@ typedef struct _GUID { ulong Data1; ushort Data2; ushort Data3; uchar Data4[ 8 ]; -} GUID; +} GUID, *REFGUID, *LPGUID; #endif #endif struct Q_EXPORT QUuid { QUuid() diff --git a/qmake/include/qvaluelist.h b/qmake/include/qvaluelist.h index 54f7aec..f5cd7bb 100644 --- a/qmake/include/qvaluelist.h +++ b/qmake/include/qvaluelist.h @@ -659,7 +659,11 @@ Q_INLINE_TEMPLATES QDataStream& operator<<( QDataStream& s, const QValueList<T>& QValueListConstIterator<T> it = l.begin(); for( ; it != l.end(); ++it ) s << *it; return s; } #endif // QT_NO_DATASTREAM +#ifdef QT_QWINEXPORT +#define Q_DEFINED_QVALUELIST +#include "qwinexport.h" +#endif /* QT_QWINEXPORT */ #endif // QVALUELIST_H diff --git a/qmake/include/qvaluestack.h b/qmake/include/qvaluestack.h index 7e9bc48..c3f966e 100644 --- a/qmake/include/qvaluestack.h +++ b/qmake/include/qvaluestack.h @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of QValueStack class ** ** Created : 990925 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -51,13 +51,13 @@ public: ~QValueStack() {} void push( const T& d ) { append(d); } T pop() { T elem( this->last() ); if ( !this->isEmpty() ) - remove( this->fromLast() ); + this->remove( this->fromLast() ); return elem; } T& top() { return this->last(); } const T& top() const { return this->last(); } }; diff --git a/qmake/main.cpp b/qmake/main.cpp index eed1697..cc2d08a 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -57,14 +57,19 @@ int main(int argc, char **argv) if(!Option::parseCommandLine(argc, argv)) return 666; QDir sunworkshop42workaround = QDir::current(); QString oldpwd = sunworkshop42workaround.currentDirPath(); Option::output_dir = oldpwd; //for now this is the output dir - if(Option::output_dir.right(1) != QString(QChar(QDir::separator()))) - Option::output_dir += QDir::separator(); +#ifdef Q_WS_WIN + if ( !(Option::output_dir.length() == 3 && Option::output_dir[0].isLetter() && Option::output_dir.endsWith(":/") ) ) +#endif + { + if(Option::output_dir.right(1) != QString(QChar(QDir::separator()))) + Option::output_dir += QDir::separator(); + } QMakeProject proj; int exit_val = 0; QStringList files; if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) files << "(*hack*)"; //we don't even use files, but we do the for() body once else diff --git a/qmake/option.cpp b/qmake/option.cpp index 34b3ee2..8b7e5e8 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -79,13 +79,13 @@ Option::TARG_MODE Option::target_mode = Option::TARG_QNX6_MODE; #else Option::TARG_MODE Option::target_mode = Option::TARG_UNIX_MODE; #endif //QMAKE_GENERATE_PROJECT stuff bool Option::projfile::do_pwd = TRUE; -bool Option::projfile::do_recursive = FALSE; +bool Option::projfile::do_recursive = TRUE; QStringList Option::projfile::project_dirs; //QMAKE_GENERATE_MAKEFILE stuff QString Option::mkfile::qmakespec; int Option::mkfile::cachefile_depth = -1; bool Option::mkfile::do_deps = TRUE; @@ -94,27 +94,38 @@ bool Option::mkfile::do_dep_heuristics = TRUE; bool Option::mkfile::do_preprocess = FALSE; bool Option::mkfile::do_cache = TRUE; QString Option::mkfile::cachefile; QStringList Option::mkfile::project_files; QString Option::mkfile::qmakespec_commandline; +static Option::QMAKE_MODE default_mode(QString progname) +{ + int s = progname.findRev(Option::dir_sep); + if(s != -1) + progname = progname.right(progname.length() - (s + 1)); + if(progname == "qmakegen") + return Option::QMAKE_GENERATE_PROJECT; + return Option::QMAKE_GENERATE_MAKEFILE; +} + +QString project_builtin_regx(); bool usage(const char *a0) { fprintf(stdout, "Usage: %s [mode] [options] [files]\n" "\n" " QMake has two modes, one mode for generating project files based on\n" "some heuristics, and the other for generating makefiles. Normally you\n" "shouldn't need to specify a mode, as makefile generation is the default\n" "mode for qmake, but you may use this to test qmake on an existing project\n" "\n" "Mode:\n" - "\t-project Put qmake into project file generation mode\n" + "\t-project Put qmake into project file generation mode%s\n" "\t In this mode qmake interprets files as files to\n" "\t be built,\n" - "\t defaults to *.cpp; *.l; *.y; *.ui\n" - "\t-makefile Put qmake into makefile generation mode (default)\n" + "\t defaults to %s\n" + "\t-makefile Put qmake into makefile generation mode%s\n" "\t In this mode qmake interprets files as project files to\n" "\t be processed, if skipped qmake will try to find a project\n" "\t file in your current working directory\n" "\n" "Warnings Options:\n" "\t-Wnone Turn off all warnings\n" @@ -133,39 +144,31 @@ bool usage(const char *a0) "\t-d Increase debug level\n" "\t-t templ Overrides TEMPLATE as templ\n" "\t-tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n" "\t-help This help\n" "\t-v Version information\n" "\t-after All variable assignments after this will be\n" - "\t parsed after [files] [makefile mode only]\n" + "\t parsed after [files]\n" "\t-cache file Use file as cache [makefile mode only]\n" "\t-spec spec Use spec as QMAKESPEC [makefile mode only]\n" "\t-nocache Don't use a cache file [makefile mode only]\n" "\t-nodepend Don't generate dependencies [makefile mode only]\n" "\t-nomoc Don't generate moc targets [makefile mode only]\n" "\t-nopwd Don't look for files in pwd [ project mode only]\n" - "\t-r Recursive search [ project mode only]\n" - ,a0); + "\t-norecursive Don't do a recursive search [ project mode only]\n" + ,a0, + default_mode(a0) == Option::QMAKE_GENERATE_PROJECT ? " (default)" : "", project_builtin_regx().latin1(), + default_mode(a0) == Option::QMAKE_GENERATE_MAKEFILE ? " (default)" : ""); return FALSE; } -static Option::QMAKE_MODE default_mode(QString progname) -{ - int s = progname.findRev(Option::dir_sep); - if(s != -1) - progname = progname.right(progname.length() - (s + 1)); - if(progname == "qmakegen") - return Option::QMAKE_GENERATE_PROJECT; - return Option::QMAKE_GENERATE_MAKEFILE; -} - bool -Option::parseCommandLine(int argc, char **argv) +Option::internalParseCommandLine(int argc, char **argv, int skip) { bool before = TRUE; - for(int x = 1; x < argc; x++) { + for(int x = skip; x < argc; x++) { if(*argv[x] == '-' && strlen(argv[x]) > 1) { /* options */ QString opt = argv[x] + 1; //first param is a mode, or we default if(x == 1) { bool specified = TRUE; @@ -176,13 +179,12 @@ Option::parseCommandLine(int argc, char **argv) Option::mkfile::do_mocs = FALSE; Option::qmake_mode = Option::QMAKE_GENERATE_PRL; } else if(opt == "makefile") { Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE; } else { specified = FALSE; - Option::qmake_mode = default_mode(argv[0]); } if(specified) continue; } //all modes if(opt == "o" || opt == "output") { @@ -201,17 +203,17 @@ Option::parseCommandLine(int argc, char **argv) Option::target_mode = TARG_UNIX_MODE; } else if(opt == "win32") { Option::target_mode = TARG_WIN_MODE; } else if(opt == "d") { Option::debug_level++; } else if(opt == "version" || opt == "v" || opt == "-version") { - fprintf(stderr, "Qmake version: %s\n", qmake_version()); + fprintf(stderr, "Qmake version: %s (Qt %s)\n", qmake_version(), QT_VERSION_STR); fprintf(stderr, "Qmake is free software from Trolltech AS.\n"); return FALSE; } else if(opt == "h" || opt == "help") { - return usage(argv[0]); + return FALSE; } else if(opt == "Wall") { Option::warn_level |= WarnAll; } else if(opt == "Wparser") { Option::warn_level |= WarnParser; } else if(opt == "Wlogic") { Option::warn_level |= WarnLogic; @@ -241,22 +243,21 @@ Option::parseCommandLine(int argc, char **argv) } } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { if(opt == "nopwd") { Option::projfile::do_pwd = FALSE; } else if(opt == "r") { Option::projfile::do_recursive = TRUE; + } else if(opt == "norecursive") { + Option::projfile::do_recursive = FALSE; } else { fprintf(stderr, "***Unknown option -%s\n", opt.latin1()); - return usage(argv[0]); + return FALSE; } } } } else { - if(x == 1) - Option::qmake_mode = default_mode(argv[0]); - QString arg = argv[x]; if(arg.find('=') != -1) { if(before) Option::before_user_vars.append(arg); else Option::after_user_vars.append(arg); @@ -269,44 +270,98 @@ Option::parseCommandLine(int argc, char **argv) Option::mkfile::project_files.append(arg); else Option::projfile::project_dirs.append(arg); } } } + return TRUE; +} + + +bool +Option::parseCommandLine(int argc, char **argv) +{ + Option::moc_mod = "moc_"; + Option::lex_mod = "_lex"; + Option::yacc_mod = "_yacc"; + Option::prl_ext = ".prl"; + Option::prf_ext = ".prf"; + Option::ui_ext = ".ui"; + Option::h_ext << ".h" << ".hpp" << ".hh" << ".H" << ".hxx"; + Option::moc_ext = ".moc"; + Option::cpp_ext << ".cpp" << ".cc" << ".cxx" << ".C"; + Option::lex_ext = ".l"; + Option::yacc_ext = ".y"; + if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING) Option::qmake_mode = default_mode(argv[0]); + if(const char *envflags = getenv("QMAKEFLAGS")) { + int env_argc = 0, env_size = 0, currlen=0; + char quote = 0, **env_argv = NULL; + for(int i = 0; envflags[i]; i++) { + if(!quote && (envflags[i] == '\'' || envflags[i] == '"')) { + quote = envflags[i]; + } else if(envflags[i] == quote) { + quote = 0; + } else if(!quote && envflags[i] == ' ') { + if(currlen && env_argv && env_argv[env_argc]) { + env_argv[env_argc][currlen] = '\0'; + currlen = 0; + env_argc++; + } + } else { + if(!env_argv || env_argc > env_size) { + env_argv = (char **)realloc(env_argv, sizeof(char *)*(env_size+=10)); + for(int i2 = env_argc; i2 < env_size; i2++) + env_argv[i2] = NULL; + } + if(!env_argv[env_argc]) { + currlen = 0; + env_argv[env_argc] = (char*)malloc(255); + } + if(currlen < 255) + env_argv[env_argc][currlen++] = envflags[i]; + } + } + if(env_argv[env_argc]) { + env_argv[env_argc][currlen] = '\0'; + currlen = 0; + env_argc++; + } + internalParseCommandLine(env_argc, env_argv); + for(int i2 = 0; i2 < env_size; i2++) { + if(env_argv[i2]) + free(env_argv[i2]); + } + free(env_argv); + } + if(!internalParseCommandLine(argc, argv, 1)) + return usage(argv[0]); //last chance for defaults if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { if(Option::mkfile::qmakespec.isNull() || Option::mkfile::qmakespec.isEmpty()) Option::mkfile::qmakespec = getenv("QMAKESPEC"); //try REALLY hard to do it for them, lazy.. if(Option::mkfile::project_files.isEmpty()) { - QString proj = QDir::currentDirPath(); - proj = proj.right(proj.length() - (proj.findRev('/') + 1)) + ".pro"; - if(QFile::exists(proj)) + QString pwd = QDir::currentDirPath(), + proj = pwd + "/" + pwd.right(pwd.length() - (pwd.findRev('/') + 1)) + ".pro"; + if(QFile::exists(proj)) { Option::mkfile::project_files.append(proj); - else - return usage(argv[0]); + } else { //last try.. + QDir d(pwd, "*.pro"); + if(d.count() != 1) + return usage(argv[0]); + Option::mkfile::project_files.append(pwd + "/" + d[0]); + } } } //defaults for globals - Option::moc_mod = "moc_"; - Option::lex_mod = "_lex"; - Option::yacc_mod = "_yacc"; - Option::prl_ext = ".prl"; - Option::prf_ext = ".prf"; - Option::ui_ext = ".ui"; - Option::h_ext << ".h" << ".hpp" << ".hh" << ".H" << ".hxx"; - Option::moc_ext = ".moc"; - Option::cpp_ext << ".cpp" << ".cc" << ".cxx" << ".C"; - Option::lex_ext = ".l"; - Option::yacc_ext = ".y"; if(Option::target_mode == Option::TARG_WIN_MODE) { Option::dir_sep = "\\"; Option::obj_ext = ".obj"; } else { if(Option::target_mode == Option::TARG_MAC9_MODE) Option::dir_sep = ":"; @@ -383,19 +438,19 @@ Option::fixPathToTargetOS(const QString& in, bool fix_env, bool canonical) QString tmp(in); if(fix_env) fixEnvVariables(tmp); if(canonical) tmp = fixPath(tmp); QString rep; - if(Option::target_mode == TARG_MAC9_MODE) - rep = "[/\\\\]"; - else if(Option::target_mode == TARG_WIN_MODE) - rep = "[/]"; - else - rep = "[\\\\]"; - return tmp.replace(QRegExp(rep), Option::dir_sep); + if(Option::target_mode == TARG_MAC9_MODE) + tmp = tmp.replace('/', Option::dir_sep).replace('\\', Option::dir_sep); + else if(Option::target_mode == TARG_WIN_MODE) + tmp = tmp.replace('/', Option::dir_sep); + else + tmp = tmp.replace('\\', Option::dir_sep); + return tmp; } QString Option::fixPathToLocalOS(const QString& in, bool fix_env, bool canonical) { QString tmp(in); diff --git a/qmake/option.h b/qmake/option.h index 9a5a85a..8bd348e 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -40,13 +40,13 @@ #include "project.h" #include <qstring.h> #include <qstringlist.h> #include <qfile.h> #define QMAKE_VERSION_MAJOR 1 -#define QMAKE_VERSION_MINOR 4 +#define QMAKE_VERSION_MINOR 5 #define QMAKE_VERSION_PATCH 0 const char *qmake_version(); void fixEnvVariables(QString &x); void debug_msg(int level, const char *fmt, ...); enum QMakeWarn { @@ -113,10 +113,13 @@ struct Option static bool do_preprocess; static QString cachefile; static int cachefile_depth; static QStringList project_files; static QString qmakespec_commandline; }; + +private: + static bool internalParseCommandLine(int, char **, int=0); }; #endif /* __OPTION_H__ */ diff --git a/qmake/project.cpp b/qmake/project.cpp index 44eb503..834823d 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -63,15 +63,20 @@ static void qmake_error_msg(const char *msg) fprintf(stderr, "%s:%d: %s\n", parser.file.latin1(), parser.line_no, msg); } static QString varMap(const QString &x) { QString ret(x); - ret.replace(QRegExp("^TMAKE"), "QMAKE"); + if(ret.startsWith("TMAKE")) //tmake no more! + ret = "QMAKE" + ret.mid(5); if(ret == "INTERFACES") ret = "FORMS"; + if(ret == "QMAKE_POST_BUILD") + ret = "QMAKE_POST_LINK"; + if(ret == "TARGETDEPS") + ret = "POST_TARGETDEPS"; return ret; } static QStringList split_arg_list(const QString ¶ms) { QStringList args; @@ -103,13 +108,13 @@ static QStringList split_value_list(const QString &vals, bool do_semicolon=FALSE QValueStack<QChar> quote; for(int x = 0; x < (int)vals.length(); x++) { if(!quote.isEmpty() && vals[x] == quote.top()) { quote.pop(); } else if(vals[x] == '\'' || vals[x] == '"') { quote.push(vals[x]); - } else if(quote.isEmpty() && + } else if(quote.isEmpty() && ((do_semicolon && vals[x] == ';') || vals[x] == ' ')) { ret << vals.mid(last, x - last); last = x+1; } } if(last != (int)vals.length()) @@ -119,16 +124,18 @@ static QStringList split_value_list(const QString &vals, bool do_semicolon=FALSE QMakeProject::QMakeProject() { } bool -QMakeProject::parse(QString t, QMap<QString, QStringList> &place) +QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) { QString s = t.simplifyWhiteSpace(); - s.replace(QRegExp("#.*$"), ""); /* bye comments */ + int hash_mark = s.find('#'); + if(hash_mark != -1) //good bye comments + s = s.left(hash_mark); if(s.isEmpty()) /* blank_line */ return TRUE; if(s.stripWhiteSpace().left(1) == "}") { debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(), parser.line_no, scope_block); @@ -151,23 +158,27 @@ QMakeProject::parse(QString t, QMap<QString, QStringList> &place) QStringList val; #define SKIP_WS(d) while(*d && (*d == ' ' || *d == '\t')) d++ const char *d = s.latin1(); SKIP_WS(d); bool scope_failed = FALSE, else_line = FALSE, or_op=FALSE; int parens = 0, scope_count=0; - while(*d && *d != '=') { - if((*d == '+' || *d == '-' || *d == '*' || *d == '~')) { - if(*(d+1) == '=') { + while(*d) { + if(!parens) { + if(*d == '=') break; - } else if(*(d+1) == ' ') { - const char *k = d + 1; - SKIP_WS(k); - if(*k == '=') { - QString msg; - qmake_error_msg(*d + "must be followed immediatly by ="); - return FALSE; + if(*d == '+' || *d == '-' || *d == '*' || *d == '~') { + if(*(d+1) == '=') { + break; + } else if(*(d+1) == ' ') { + const char *k = d + 1; + SKIP_WS(k); + if(*k == '=') { + QString msg; + qmake_error_msg(*d + "must be followed immediately by ="); + return FALSE; + } } } } if ( *d == '(' ) ++parens; @@ -214,13 +225,13 @@ QMakeProject::parse(QString t, QMap<QString, QStringList> &place) if(invert_test) test = !test; test_status = (test ? TestFound : TestSeek); return TRUE; /* assume we are done */ } } else { - test = isActiveConfig(comp_scope.stripWhiteSpace()); + test = isActiveConfig(comp_scope.stripWhiteSpace(), TRUE); } if(invert_test) test = !test; } } if(!test && !scope_failed) @@ -284,13 +295,13 @@ QMakeProject::parse(QString t, QMap<QString, QStringList> &place) } fprintf(stderr, "%s %s %s\n", var.latin1(), op.latin1(), vals.latin1()); } var = varMap(var); //backwards compatability /* vallist is the broken up list of values */ - QStringList vallist = split_value_list(vals, (var == "DEPENDPATH" || var == "INCLUDEPATH")); + QStringList vallist = split_value_list(vals, (var == "DEPENDPATH" || var == "INCLUDEPATH")); if(!vallist.grep("=").isEmpty()) warn_msg(WarnParser, "Detected possible line continuation: {%s} %s:%d", var.latin1(), parser.file.latin1(), parser.line_no); QStringList &varlist = place[var]; /* varlist is the list in the symbol table */ debug_msg(1, "Project Parser: %s:%d :%s: :%s: (%s)", parser.file.latin1(), parser.line_no, @@ -352,42 +363,46 @@ QMakeProject::parse(QString t, QMap<QString, QStringList> &place) doProjectCheckReqs(vallist, place); return TRUE; } bool -QMakeProject::read(QString file, QMap<QString, QStringList> &place) +QMakeProject::read(const QString &file, QMap<QString, QStringList> &place) { parser_info pi = parser; /* scope blocks start at true */ test_status = TestNone; scope_flag = 0x01; scope_block = 0; - file = Option::fixPathToLocalOS(file); - doVariableReplace(file, place); + QString filename = Option::fixPathToLocalOS(file); + doVariableReplace(filename, place); bool ret = FALSE, using_stdin = FALSE; QFile qfile; - if(!strcmp(file, "-")) { + if(!strcmp(filename, "-")) { qfile.setName(""); ret = qfile.open(IO_ReadOnly, stdin); using_stdin = TRUE; } else { - qfile.setName(file); + qfile.setName(filename); ret = qfile.open(IO_ReadOnly); } if ( ret ) { QTextStream t( &qfile ); QString s, line; - parser.file = file; + parser.file = filename; parser.line_no = 0; while ( !t.eof() ) { parser.line_no++; line = t.readLine().stripWhiteSpace(); int prelen = line.length(); - line.replace(QRegExp("#.*$"), ""); // bye comments + { + int hash_mark = line.find('#'); + if(hash_mark != -1) //bye comments + line = line.left(hash_mark); + } if(!line.isEmpty() && line.right(1) == "\\") { line.truncate(line.length() - 1); s += line + " "; } else if(!line.isEmpty() || (line.isEmpty() && !prelen)) { if(s.isEmpty() && line.isEmpty()) continue; @@ -405,18 +420,27 @@ QMakeProject::read(QString file, QMap<QString, QStringList> &place) } parser = pi; return ret; } bool -QMakeProject::read(QString project, QString) +QMakeProject::read(const QString &project, const QString &, bool just_project) { + if(just_project) { //nothing more, nothing less + pfile = project; + if(pfile != "-" && !QFile::exists(pfile) && pfile.right(4) != ".pro") + pfile += ".pro"; + return read(pfile, vars); + } + if(cfile.isEmpty()) { // hack to get the Option stuff in there base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext; base_vars["QMAKE_EXT_H"] = Option::h_ext; + if(!Option::user_template_prefix.isEmpty()) + base_vars["TEMPLATE_PREFIX"] = Option::user_template_prefix; /* parse the cache */ if(Option::mkfile::do_cache) { if(Option::mkfile::cachefile.isEmpty()) { //find it as it has not been specified QString dir = QDir::convertSeparators(Option::output_dir); while(!QFile::exists((Option::mkfile::cachefile = dir + @@ -438,40 +462,28 @@ QMakeProject::read(QString project, QString) Option::mkfile::qmakespec = cache["QMAKESPEC"].first(); } } /* parse mkspec */ QStringList mkspec_roots; /* prefer $QTDIR if it is set */ - /* prefer QMAKESPECSDIR -cl */ - - if (getenv("QTDIR")) { + if (getenv("QTDIR")) mkspec_roots << getenv("QTDIR"); - } mkspec_roots << qInstallPathData(); - - if (Option::mkfile::qmakespec.isEmpty() && getenv("QMAKESPECSDIR")){ - QString mkspec = QString(getenv("QMAKESPECSDIR")) + QDir::separator() + - QDir::separator() + "default"; - if(QFile::exists(mkspec)) - Option::mkfile::qmakespec = mkspec; - } - if(Option::mkfile::qmakespec.isEmpty()) { for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { QString mkspec = (*it) + QDir::separator() + QString("mkspecs") + QDir::separator() + "default"; if(QFile::exists(mkspec)) { Option::mkfile::qmakespec = mkspec; break; } } - } - - if(Option::mkfile::qmakespec.isEmpty()) { - fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n"); - return FALSE; + if(Option::mkfile::qmakespec.isEmpty()) { + fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n"); + return FALSE; + } } if(QDir::isRelativePath(Option::mkfile::qmakespec)) { bool found_mkspec = FALSE; for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { QString mkspec = (*it) + QDir::separator() + QString("mkspecs") + @@ -541,18 +553,20 @@ QMakeProject::read(QString project, QString) if(!Option::user_template.isEmpty()) { debug_msg(1, "Overriding TEMPLATE (%s) with: %s", vars["TEMPLATE"].first().latin1(), Option::user_template.latin1()); vars["TEMPLATE"].clear(); vars["TEMPLATE"].append(Option::user_template); } - if(vars["TEMPLATE"].isEmpty()) - vars["TEMPLATE"].append(QString("app")); - else - vars["TEMPLATE"].first().replace(QRegExp("\\.t$"), ""); - if(!Option::user_template_prefix.isEmpty()) - vars["TEMPLATE"].first().prepend(Option::user_template_prefix); + QStringList &templ = vars["TEMPLATE"]; + if(templ.isEmpty()) + templ.append(QString("app")); + else if(vars["TEMPLATE"].first().endsWith(".t")) + templ = QStringList(templ.first().left(templ.first().length() - 2)); + if ( !Option::user_template_prefix.isEmpty() ) { + templ.first().prepend(Option::user_template_prefix); + } if(vars["TARGET"].isEmpty()) { // ### why not simply use: // QFileInfo fi(pfile); // fi.baseName(); QString tmp = pfile; @@ -576,20 +590,19 @@ QMakeProject::read(QString project, QString) } } return TRUE; } bool -QMakeProject::isActiveConfig(const QString &x) +QMakeProject::isActiveConfig(const QString &x, bool regex) { if(x.isEmpty()) return TRUE; - QRegExp re(x, FALSE, TRUE); - if((Option::target_mode == Option::TARG_MACX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || Option::target_mode == Option::TARG_UNIX_MODE) && - x == "unix") + if((Option::target_mode == Option::TARG_MACX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || + Option::target_mode == Option::TARG_UNIX_MODE) && x == "unix") return TRUE; else if(Option::target_mode == Option::TARG_MACX_MODE && x == "macx") return TRUE; else if(Option::target_mode == Option::TARG_QNX6_MODE && x == "qnx6") return TRUE; else if(Option::target_mode == Option::TARG_MAC9_MODE && x == "mac9") @@ -598,65 +611,77 @@ QMakeProject::isActiveConfig(const QString &x) x == "mac") return TRUE; else if(Option::target_mode == Option::TARG_WIN_MODE && x == "win32") return TRUE; + QRegExp re(x, FALSE, TRUE); QString spec = Option::mkfile::qmakespec.right(Option::mkfile::qmakespec.length() - (Option::mkfile::qmakespec.findRev(QDir::separator())+1)); - if(re.exactMatch(spec)) + if((regex && re.exactMatch(spec)) || (!regex && spec == x)) return TRUE; #ifdef Q_OS_UNIX else if(spec == "default") { static char *buffer = NULL; if(!buffer) buffer = (char *)malloc(1024); int l = readlink(Option::mkfile::qmakespec, buffer, 1024); if(l != -1) { buffer[l] = '\0'; QString r = buffer; if(r.findRev('/') != -1) r = r.mid(r.findRev('/') + 1); - if(re.exactMatch(r)) + if((regex && re.exactMatch(r)) || (!regex && r == x)) return TRUE; } } #endif QStringList &configs = vars["CONFIG"]; for(QStringList::Iterator it = configs.begin(); it != configs.end(); ++it) { + if((regex && re.exactMatch((*it))) || (!regex && (*it) == x)) if(re.exactMatch((*it))) return TRUE; } return FALSE; } bool -QMakeProject::doProjectTest(QString func, const QString ¶ms, QMap<QString, QStringList> &place) +QMakeProject::doProjectTest(const QString& func, const QString ¶ms, QMap<QString, QStringList> &place) { QStringList args = split_arg_list(params); for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { QString tmp = (*arit).stripWhiteSpace(); if((tmp[0] == '\'' || tmp[0] == '"') && tmp.right(1) == tmp.left(1)) tmp = tmp.mid(1, tmp.length() - 2); } return doProjectTest(func.stripWhiteSpace(), args, place); } bool -QMakeProject::doProjectTest(QString func, QStringList args, QMap<QString, QStringList> &place) +QMakeProject::doProjectTest(const QString& func, QStringList args, QMap<QString, QStringList> &place) { for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { (*arit) = (*arit).stripWhiteSpace(); // blah, get rid of space doVariableReplace((*arit), place); } debug_msg(1, "Running project test: %s( %s )", func.latin1(), args.join("::").latin1()); if(func == "requires") { return doProjectCheckReqs(args, place); + } else if(func == "equals") { + if(args.count() != 2) { + fprintf(stderr, "%s:%d: equals(variable, value) requires two arguments.\n", parser.file.latin1(), + parser.line_no); + return FALSE; + } + QString value = args[1]; + if((value.left(1) == "\"" || value.left(1) == "'") && value.right(1) == value.left(1)) + value = value.mid(1, value.length()-2); + return vars[args[0]].join(" ") == value; } else if(func == "exists") { if(args.count() != 1) { fprintf(stderr, "%s:%d: exists(file) requires one argument.\n", parser.file.latin1(), parser.line_no); return FALSE; } @@ -688,13 +713,13 @@ QMakeProject::doProjectTest(QString func, QStringList args, QMap<QString, QStrin parser.line_no); return FALSE; } QRegExp regx(args[1]); QStringList &l = place[args[0]]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { - if(regx.exactMatch((*it))) + if(regx.exactMatch((*it))) return TRUE; } return FALSE; } else if(func == "infile") { if(args.count() < 2 || args.count() > 3) { fprintf(stderr, "%s:%d: infile(file, var, val) requires at least 2 arguments.\n", @@ -802,26 +827,34 @@ QMakeProject::doProjectTest(QString func, QStringList args, QMap<QString, QStrin debug_msg(1, "Project Parser: %s'ing file %s.", func.latin1(), file.latin1()); parser_info pi = parser; int sb = scope_block; int sf = scope_flag; TestStatus sc = test_status; bool r = read(file.latin1(), place); - if(r) + if(r) vars["QMAKE_INTERNAL_INCLUDED_FILES"].append(file); + else + warn_msg(WarnParser, "%s:%d: Failure to include file %s.", + pi.file.latin1(), pi.line_no, file.latin1()); parser = pi; test_status = sc; scope_flag = sf; scope_block = sb; return r; } else if(func == "error" || func == "message") { if(args.count() != 1) { fprintf(stderr, "%s:%d: %s(message) requires one argument.\n", parser.file.latin1(), parser.line_no, func.latin1()); return FALSE; } QString msg = args.first(); + if((msg.startsWith("\"") || msg.startsWith("'")) && msg.endsWith(msg.left(1))) + msg = msg.mid(1, msg.length()-2); + msg.replace(QString("${QMAKE_FILE}"), parser.file.latin1()); + msg.replace(QString("${QMAKE_LINE_NUMBER}"), QString::number(parser.line_no)); + msg.replace(QString("${QMAKE_DATE}"), QDateTime::currentDateTime().toString()); doVariableReplace(msg, place); fixEnvVariables(msg); printf("Project %s: %s\n", func.upper().latin1(), msg.latin1()); if(func == "message") return TRUE; exit(2); @@ -854,13 +887,13 @@ QMakeProject::doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringL qmake_error_msg(error); } else { QString func = chk.left(lparen); test = doProjectTest(func, chk.mid(lparen+1, rparen - lparen - 1), place); } } else { - test = isActiveConfig(chk); + test = isActiveConfig(chk, TRUE); } if(invert_test) { chk.prepend("!"); test = !test; } if(!test) { @@ -874,121 +907,171 @@ QMakeProject::doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringL } QString QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> &place) { - for(int x = 0, rep; x < 5; x++) { - QRegExp reg_var; - reg_var.setMinimal(TRUE); - if( x == 0 ) //function blocked out by {}'s - reg_var = QRegExp("\\$\\$\\{([a-zA-Z0-9_]*)\\((\\(.|(.*)\\)*)\\)\\}"); - else if( x == 1 ) //variables blocked out by {}'s - reg_var = QRegExp("\\$\\$\\{([a-zA-Z0-9_\\.-]*)\\}"); - else if(x == 2) //environment - reg_var = QRegExp("\\$\\$\\(([a-zA-Z0-9_\\.-]*)\\)"); - else if(x == 3) //function - reg_var = QRegExp("\\$\\$([a-zA-Z0-9_]*)\\((\\(.|(.*)\\)*)\\)"); - else if(x == 4) //normal variable - reg_var = QRegExp("\\$\\$([a-zA-Z0-9_\\.-]*)"); - while((rep = reg_var.search(str)) != -1) { - QString replacement; - if(x == 2) {//environment - replacement = getenv(reg_var.cap(1)); - } else if(x == 0 || x == 3) { //function - QStringList args = split_arg_list(reg_var.cap(2)); - for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { - (*arit) = (*arit).stripWhiteSpace(); // blah, get rid of space - doVariableReplace((*arit), place); - } - debug_msg(1, "Running function: %s( %s )", reg_var.cap(1).latin1(), args.join("::").latin1()); - if(reg_var.cap(1).lower() == "member") { - if(args.count() < 1 || args.count() > 2) { - fprintf(stderr, "%s:%d: member(var, place) requires two arguments.\n", - parser.file.latin1(), parser.line_no); - } else { - uint pos = 0; - if(args.count() == 2) - pos = args[1].toInt(); - const QStringList &var = place[varMap(args.first())]; - if(var.count() >= pos) - replacement = var[pos]; - } - } else if(reg_var.cap(1).lower() == "list") { - if(args.count() != 1) { - fprintf(stderr, "%s:%d: list(vals) requires one" - "argument.\n", parser.file.latin1(), parser.line_no); - } else { - static int x = 0; - replacement.sprintf(".QMAKE_INTERNAL_TMP_VAR_%d", x++); - (*((QMap<QString, QStringList>*)&place))[replacement] = split_value_list(args.first()); - } - } else if(reg_var.cap(1).lower() == "join") { - if(args.count() < 1 || args.count() > 4) { - fprintf(stderr, "%s:%d: join(var, glue, before, after) requires four" - "arguments.\n", parser.file.latin1(), parser.line_no); - } else { - QString glue, before, after; - if(args.count() >= 2) - glue = args[1].replace("\"", "" ); - if(args.count() >= 3) - before = args[2].replace("\"", "" ); - if(args.count() == 4) - after = args[3].replace("\"", "" ); - const QStringList &var = place[varMap(args.first())]; - if(!var.isEmpty()) - replacement = before + var.join(glue) + after; + for(int var_begin, var_last=0; (var_begin = str.find("$$", var_last)) != -1; var_last = var_begin) { + if(var_begin >= int( str.length() + 2 ) ) { + break; + } else if(var_begin != 0 && str[var_begin-1] == '\\') { + str.replace(var_begin-1, 1, ""); + var_begin += 1; + continue; + } + + int var_incr = var_begin + 2; + bool in_braces = FALSE, as_env = FALSE; + if(str[var_incr] == '{') { + in_braces = TRUE; + var_incr++; + while(var_incr < int( str.length() ) && + (str[var_incr] == ' ' || str[var_incr] == '\t' || str[var_incr] == '\n')) + var_incr++; + } + if(str[var_incr] == '(') { + as_env = TRUE; + var_incr++; + } + QString val, args; + while(var_incr < int( str.length() ) && + (str[var_incr].isLetter() || str[var_incr].isNumber() || str[var_incr] == '.' || str[var_incr] == '_')) + val += str[var_incr++]; + if(as_env) { + if(str[var_incr] != ')') { + var_incr++; + warn_msg(WarnParser, "%s:%d: Unterminated env-variable replacement '%s' (%s)", + parser.file.latin1(), parser.line_no, + str.mid(var_begin, QMAX(var_incr - var_begin, int(str.length()))).latin1(), str.latin1()); + var_begin += var_incr; + continue; + } + var_incr++; + } else if(str[var_incr] == '(') { //args + for(int parens = 0; var_incr < int( str.length() ); var_incr++) { + if(str[var_incr] == '(') { + parens++; + if(parens == 1) + continue; + } else if(str[var_incr] == ')') { + parens--; + if(!parens) { + var_incr++; + break; } - } else if(reg_var.cap(1).lower() == "find") { - if(args.count() != 2) { - fprintf(stderr, "%s:%d find(var, str) requires two arguments\n", - parser.file.latin1(), parser.line_no); - } else { - QRegExp regx(args[1]); - const QStringList &var = place[varMap(args.first())]; - for(QStringList::ConstIterator vit = var.begin(); - vit != var.end(); ++vit) { - if(regx.search(*vit) != -1) { - if(!replacement.isEmpty()) - replacement += " "; - replacement += (*vit); - } + } + args += str[var_incr]; + } + } + if(var_incr > int( str.length() ) || (in_braces && str[var_incr] != '}')) { + var_incr++; + warn_msg(WarnParser, "%s:%d: Unterminated variable replacement '%s' (%s)", + parser.file.latin1(), parser.line_no, + str.mid(var_begin, QMAX(var_incr - var_begin, int( str.length() ))).latin1(), str.latin1()); + var_begin += var_incr; + continue; + } else if(in_braces) { + var_incr++; + } + + QString replacement; + if(as_env) { + replacement = getenv(val); + } else if(args.isEmpty()) { + if(val.left(1) == ".") + replacement = ""; + else if(val == "LITERAL_WHITESPACE") + replacement = "\t"; + else + replacement = place[varMap(val)].join(" "); + } else { + QStringList arg_list = split_arg_list(args); + for(QStringList::Iterator arit = arg_list.begin(); arit != arg_list.end(); ++arit) { + (*arit) = (*arit).stripWhiteSpace(); // blah, get rid of space + doVariableReplace((*arit), place); + } + debug_msg(1, "Running function: %s( %s )", val.latin1(), arg_list.join("::").latin1()); + if(val.lower() == "member") { + if(arg_list.count() < 1 || arg_list.count() > 2) { + fprintf(stderr, "%s:%d: member(var, place) requires two arguments.\n", + parser.file.latin1(), parser.line_no); + } else { + uint pos = 0; + if(arg_list.count() == 2) + pos = arg_list[1].toInt(); + const QStringList &var = place[varMap(arg_list.first())]; + if(var.count() >= pos) + replacement = var[pos]; + } + } else if(val.lower() == "list") { + static int x = 0; + replacement.sprintf(".QMAKE_INTERNAL_TMP_VAR_%d", x++); + QStringList &lst = (*((QMap<QString, QStringList>*)&place))[replacement]; + lst.clear(); + for(QStringList::ConstIterator arg_it = arg_list.begin(); + arg_it != arg_list.end(); ++arg_it) + lst += split_value_list((*arg_it)); + } else if(val.lower() == "join") { + if(arg_list.count() < 1 || arg_list.count() > 4) { + fprintf(stderr, "%s:%d: join(var, glue, before, after) requires four" + "arguments.\n", parser.file.latin1(), parser.line_no); + } else { + QString glue, before, after; + if(arg_list.count() >= 2) + glue = arg_list[1].replace("\"", "" ); + if(arg_list.count() >= 3) + before = arg_list[2].replace("\"", "" ); + if(arg_list.count() == 4) + after = arg_list[3].replace("\"", "" ); + const QStringList &var = place[varMap(arg_list.first())]; + if(!var.isEmpty()) + replacement = before + var.join(glue) + after; + } + } else if(val.lower() == "find") { + if(arg_list.count() != 2) { + fprintf(stderr, "%s:%d find(var, str) requires two arguments\n", + parser.file.latin1(), parser.line_no); + } else { + QRegExp regx(arg_list[1]); + const QStringList &var = place[varMap(arg_list.first())]; + for(QStringList::ConstIterator vit = var.begin(); + vit != var.end(); ++vit) { + if(regx.search(*vit) != -1) { + if(!replacement.isEmpty()) + replacement += " "; + replacement += (*vit); } } - } else if(reg_var.cap(1).lower() == "system") { - if(args.count() != 1) { - fprintf(stderr, "%s:%d system(execut) requires one argument\n", - parser.file.latin1(), parser.line_no); - } else { - char buff[256]; - FILE *proc = QT_POPEN(args.join(" ").latin1(), "r"); - while(proc && !feof(proc)) { - int read_in = 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'; - replacement += buff; + } + } else if(val.lower() == "system") { + if(arg_list.count() != 1) { + fprintf(stderr, "%s:%d system(execut) requires one argument\n", + parser.file.latin1(), parser.line_no); + } else { + char buff[256]; + FILE *proc = QT_POPEN(arg_list.join(" ").latin1(), "r"); + while(proc && !feof(proc)) { + int read_in = 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'; + replacement += buff; } - } else { - fprintf(stderr, "%s:%d: Unknown replace function: %s\n", - parser.file.latin1(), parser.line_no, reg_var.cap(1).latin1()); } - } else { //variable - if(reg_var.cap(1).left(1) == ".") - replacement = ""; - else if(reg_var.cap(1) == "LITERAL_WHITESPACE") - replacement = "\t"; - else - replacement = place[varMap(reg_var.cap(1))].join(" "); + } else { + fprintf(stderr, "%s:%d: Unknown replace function: %s\n", + parser.file.latin1(), parser.line_no, val.latin1()); } - debug_msg(2, "Project parser: %d (%s) :: %s -> %s", x, str.latin1(), - reg_var.capturedTexts().join("::").latin1(), replacement.latin1()); - str.replace(rep, reg_var.matchedLength(), replacement); } + //actually do replacement now.. + int mlen = var_incr - var_begin; + debug_msg(2, "Project Parser [var replace]: '%s' :: %s -> %s", str.latin1(), + str.mid(var_begin, mlen).latin1(), replacement.latin1()); + str.replace(var_begin, mlen, replacement); + var_begin += replacement.length(); } return str; } diff --git a/qmake/project.h b/qmake/project.h index 201e63c..ec19f0c 100644 --- a/qmake/project.h +++ b/qmake/project.h @@ -2,13 +2,13 @@ ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -31,48 +31,48 @@ ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef __QMAKE_H__ -#define __QMAKE_H__ +#ifndef __PROJECT_H__ +#define __PROJECT_H__ #include <qstringlist.h> #include <qstring.h> #include <qmap.h> class QMakeProject { enum TestStatus { TestNone, TestFound, TestSeek } test_status; int scope_block, scope_flag; QString pfile, cfile; QMap<QString, QStringList> vars, base_vars, cache; - bool parse(QString text, QMap<QString, QStringList> &place); - bool doProjectTest(QString func, const QString ¶ms, QMap<QString, QStringList> &place); - bool doProjectTest(QString func, QStringList args, QMap<QString, QStringList> &place); + bool parse(const QString &text, QMap<QString, QStringList> &place); + bool doProjectTest(const QString &func, const QString ¶ms, QMap<QString, QStringList> &place); + bool doProjectTest(const QString &func, QStringList args, QMap<QString, QStringList> &place); bool doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringList> &place); QString doVariableReplace(QString &str, const QMap<QString, QStringList> &place); public: QMakeProject(); - bool read(QString project, QString pwd); + bool read(const QString &project, const QString &pwd, bool just_project=FALSE); QString projectFile(); QString configFile(); bool isEmpty(const QString &v); QStringList &values(const QString &v); QString first(const QString &v); QMap<QString, QStringList> &variables(); - bool isActiveConfig(const QString &x); + bool isActiveConfig(const QString &x, bool regex=FALSE); protected: friend class MakefileGenerator; - bool read(QString file, QMap<QString, QStringList> &place); + bool read(const QString &file, QMap<QString, QStringList> &place); }; inline QString QMakeProject::projectFile() { #if defined(Q_CC_SUN) && (__SUNPRO_CC == 0x500) || defined(Q_CC_HP) @@ -108,7 +108,7 @@ inline QString QMakeProject::first(const QString &v) #endif } inline QMap<QString, QStringList> &QMakeProject::variables() { return vars; } -#endif /* __QMAKE_H__ */ +#endif /* __PROJECT_H__ */ diff --git a/qmake/tools/qbitarray.cpp b/qmake/tools/qbitarray.cpp index 4f4e14b..1aaf963 100644 --- a/qmake/tools/qbitarray.cpp +++ b/qmake/tools/qbitarray.cpp @@ -194,13 +194,14 @@ void QBitArray::pad0() \sa resize() */ /*! Resizes the bit array to \a size bits and returns TRUE if the bit - array could be resized; otherwise returns FALSE. + array could be resized; otherwise returns FALSE. The array becomes + a null array if \a size == 0. If the array is expanded, the new bits are set to 0. \sa size() */ diff --git a/qmake/tools/qbuffer.cpp b/qmake/tools/qbuffer.cpp index b213dd9..0fc90e4 100644 --- a/qmake/tools/qbuffer.cpp +++ b/qmake/tools/qbuffer.cpp @@ -193,14 +193,14 @@ bool QBuffer::open( int m ) qWarning( "QBuffer::open: Buffer already open" ); #endif return FALSE; } setMode( m ); if ( m & IO_Truncate ) { // truncate buffer - a.resize( 0 ); - a_len = 0; + a.resize( 1 ); + a_len = 1; } if ( m & IO_Append ) { // append to end of buffer ioIndex = a.size(); } else { ioIndex = 0; } diff --git a/qmake/tools/qcomlibrary.cpp b/qmake/tools/qcomlibrary.cpp index a7162fc..2a1b75a 100644 --- a/qmake/tools/qcomlibrary.cpp +++ b/qmake/tools/qcomlibrary.cpp @@ -60,12 +60,16 @@ QComLibrary::QComLibrary( const QString &filename ) } QComLibrary::~QComLibrary() { if ( autoUnload() ) unload(); + if ( libiface ) + libiface->release(); + if ( entry ) + entry->release(); } bool QComLibrary::unload() { if ( libiface ) { libiface->cleanup(); @@ -388,35 +392,33 @@ void QComLibrary::createInstanceInternal() QStringList reg; uint flags = 0; QCString key; bool query_done = FALSE; bool warn_mismatch = TRUE; - if ( ! query_done ) { - #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &cache ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &cache ) : 0 ); #endif // QT_THREAD_SUPPORT - if ( ! cache ) { - cache = new QSettings; - cache->insertSearchPath( QSettings::Windows, "/Trolltech" ); - cleanup_cache.set( &cache ); - } + if ( ! cache ) { + cache = new QSettings; + cache->insertSearchPath( QSettings::Windows, "/Trolltech" ); + cleanup_cache.set( &cache ); + } - reg = cache->readListEntry( regkey ); - if ( reg.count() == 4 ) { - // check timestamp - if ( lastModified == reg[3] ) { - qt_version = reg[0].toUInt(0, 16); - flags = reg[1].toUInt(0, 16); - key = reg[2].latin1(); + reg = cache->readListEntry( regkey ); + if ( reg.count() == 4 ) { + // check timestamp + if ( lastModified == reg[3] ) { + qt_version = reg[0].toUInt(0, 16); + flags = reg[1].toUInt(0, 16); + key = reg[2].latin1(); - query_done = TRUE; - warn_mismatch = FALSE; - } + query_done = TRUE; + warn_mismatch = FALSE; } } #if defined(Q_OS_UNIX) if ( ! query_done ) { // get the query information directly from the plugin without loading @@ -458,17 +460,12 @@ void QComLibrary::createInstanceInternal() queried << QString::number( qt_version,16 ) << QString::number( flags, 16 ) << key << lastModified; if ( queried != reg ) { - -#ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &cache ) ); -#endif // QT_THREAD_SUPPORT - cache->writeEntry( regkey, queried ); // delete the cache, which forces the settings to be written delete cache; cache = 0; } diff --git a/qmake/tools/qconfig.cpp b/qmake/tools/qconfig.cpp index 433827c..5297a4e 100644 --- a/qmake/tools/qconfig.cpp +++ b/qmake/tools/qconfig.cpp @@ -1,15 +1,15 @@ /* Install paths from configure */ -static const char QT_INSTALL_PREFIX [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2"; -static const char QT_INSTALL_BINS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/bin"; -static const char QT_INSTALL_DOCS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/doc"; -static const char QT_INSTALL_HEADERS[256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/include"; -static const char QT_INSTALL_LIBS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/lib"; -static const char QT_INSTALL_PLUGINS[256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/plugins"; -static const char QT_INSTALL_DATA [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2"; +static const char QT_INSTALL_PREFIX [256] = "/opt/qt-x11-free-3.1.2"; +static const char QT_INSTALL_BINS [256] = "/opt/qt-x11-free-3.1.2/bin"; +static const char QT_INSTALL_DOCS [256] = "/opt/qt-x11-free-3.1.2/doc"; +static const char QT_INSTALL_HEADERS[256] = "/opt/qt-x11-free-3.1.2/include"; +static const char QT_INSTALL_LIBS [256] = "/opt/qt-x11-free-3.1.2/lib"; +static const char QT_INSTALL_PLUGINS[256] = "/opt/qt-x11-free-3.1.2/plugins"; +static const char QT_INSTALL_DATA [256] = "/opt/qt-x11-free-3.1.2"; const char *qInstallPath() { return QT_INSTALL_PREFIX; } const char *qInstallPathDocs() { return QT_INSTALL_DOCS; } const char *qInstallPathHeaders() { return QT_INSTALL_HEADERS; } const char *qInstallPathLibs() { return QT_INSTALL_LIBS; } const char *qInstallPathBins() { return QT_INSTALL_BINS; } diff --git a/qmake/tools/qcriticalsection_p.cpp b/qmake/tools/qcriticalsection_p.cpp index 60fc8bd..c375730 100644 --- a/qmake/tools/qcriticalsection_p.cpp +++ b/qmake/tools/qcriticalsection_p.cpp @@ -1,13 +1,11 @@ /**************************************************************************** ** $Id$ ** ** Implementation of QCriticalSection class ** -** Created : -** ** Copyright (C) 2001 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file diff --git a/qmake/tools/qcstring.cpp b/qmake/tools/qcstring.cpp index cf1b853..4651b97 100644 --- a/qmake/tools/qcstring.cpp +++ b/qmake/tools/qcstring.cpp @@ -138,12 +138,23 @@ char *qstrncpy( char *dst, const char *src, uint len ) if ( len > 0 ) dst[len-1] = '\0'; return dst; } /*! + \fn uint qstrlen( const char *str ); + + \relates QCString + + A safe strlen function. + + Returns the number of characters that precede the terminating '\0'. + or 0 if \a str is 0. +*/ + +/*! \fn int qstrcmp( const char *str1, const char *str2 ); \relates QCString A safe strcmp() function. @@ -296,13 +307,14 @@ static void createCRC16Table() // build CRC16 lookup table Q_UINT16 qChecksum( const char *data, uint len ) { if ( !crc_tbl_init ) { // create lookup table #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &crc_tbl_init ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &crc_tbl_init ) : 0 ); #endif // QT_THREAD_SUPPORT if ( !crc_tbl_init ) { createCRC16Table(); crc_tbl_init = TRUE; } @@ -316,24 +328,30 @@ Q_UINT16 qChecksum( const char *data, uint len ) c >>= 4; crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)]; } return ~crc & 0xffff; } -/*! \fn QByteArray qCompress( const QByteArray& data) - \relates QByteArray - \overload +/*! + \fn QByteArray qCompress( const QByteArray& data ) + + \relates QByteArray + + Compresses the array \a data and returns the compressed byte + array. + + \sa qUncompress() */ /*! - \relates QByteArray + \relates QByteArray - Compresses the array \a data which is \a nbytes long and returns the - compressed byte array. + \overload - \sa qUncompress() + Compresses the array \a data which is \a nbytes long and returns the + compressed byte array. */ #ifndef QT_NO_COMPRESS QByteArray qCompress( const uchar* data, int nbytes ) { if ( nbytes == 0 ) { @@ -376,26 +394,38 @@ QByteArray qCompress( const uchar* data, int nbytes ) } while ( res == Z_BUF_ERROR ); return bazip; } #endif -/*! \fn QByteArray qUncompress( const QByteArray& data ) - \relates QByteArray - \overload +/*! + \fn QByteArray qUncompress( const QByteArray& data ) + + \relates QByteArray + + Uncompresses the array \a data and returns the uncompressed byte + array. + + Returns an empty QByteArray if the input data was corrupt. + \omit + ADD THE FOLLOWING FOR Qt 4.0 + This function will uncompress data compressed with qCompress() + from this and any earlier Qt version, back to Qt 3.1 when this + feature was added. + \endomit + + \sa qCompress() */ /*! - \relates QByteArray - - Uncompresses the array \a data which is \a nbytes long and returns - the uncompressed byte array. + \relates QByteArray - Returns an empty QByteArray if the input data was corrupt. + \overload - \sa qCompress() + Uncompresses the array \a data which is \a nbytes long and returns + the uncompressed byte array. */ #ifndef QT_NO_COMPRESS QByteArray qUncompress( const uchar* data, int nbytes ) { if ( !data ) { @@ -933,19 +963,23 @@ int QCString::find( char c, int index, bool cs ) const \sa \link #asciinotion Note on character comparisons \endlink */ int QCString::find( const char *str, int index, bool cs ) const { + return find( str, index, cs, length() ); +} + +int QCString::find( const char *str, int index, bool cs, uint l ) const +{ if ( (uint)index >= size() ) return -1; if ( !str ) return -1; if ( !*str ) return index; - const uint l = length(); const uint sl = qstrlen( str ); if ( sl + index > l ) return -1; if ( sl == 1 ) return find( *str, index, cs ); @@ -1149,14 +1183,15 @@ int QCString::contains( char c, bool cs ) const */ int QCString::contains( const char *str, bool cs ) const { int count = 0; int i = -1; + uint l = length(); // use find for the faster hashing algorithm - while ( ( i = find ( str, i+1, cs ) ) != -1 ) + while ( ( i = find ( str, i+1, cs, l ) ) != -1 ) count++; return count; } /*! Returns a substring that contains the \a len leftmost characters @@ -1170,13 +1205,12 @@ int QCString::contains( const char *str, bool cs ) const QCString s = "Pineapple"; QCString t = s.left( 4 ); // t == "Pine" \endcode \sa right(), mid() */ - QCString QCString::left( uint len ) const { if ( isEmpty() ) { QCString empty; return empty; } else if ( len >= size() ) { @@ -1494,20 +1528,22 @@ QCString &QCString::insert( uint index, const char *s ) if ( len == 0 ) return *this; uint olen = length(); int nlen = olen + len; if ( index >= olen ) { // insert after end of string detach(); - if ( QByteArray::resize(nlen+index-olen+1) ) { + if ( QByteArray::resize(nlen+index-olen+1, QByteArray::SpeedOptim ) ) { memset( data()+olen, ' ', index-olen ); memcpy( data()+index, s, len+1 ); } - } else if ( QByteArray::resize(nlen+1) ) { // normal insert + } else { detach(); - memmove( data()+index+len, data()+index, olen-index+1 ); - memcpy( data()+index, s, len ); + if ( QByteArray::resize(nlen+1, QByteArray::SpeedOptim ) ) { // normal insert + memmove( data()+index+len, data()+index, olen-index+1 ); + memcpy( data()+index, s, len ); + } } return *this; } /*! Inserts character \a c into the string at position \a index and @@ -1566,13 +1602,13 @@ QCString &QCString::remove( uint index, uint len ) detach(); resize( index+1 ); } } else if ( len != 0 ) { detach(); memmove( data()+index, data()+index+len, olen-index-len+1 ); - QByteArray::resize(olen-len+1); + QByteArray::resize(olen-len+1, QByteArray::SpeedOptim ); } return *this; } /*! Replaces \a len characters from the string, starting at position @@ -1628,12 +1664,13 @@ QCString &QCString::replace( char c, const char *after ) \code QCString s = "Greek is Greek"; s.replace( "Greek", "English" ); // s == "English is English" \endcode */ + QCString &QCString::replace( const char *before, const char *after ) { if ( before == after || isNull() ) return *this; detach(); @@ -1643,22 +1680,22 @@ QCString &QCString::replace( const char *before, const char *after ) const int al = after ? strlen( after ) : 0; char *d = data(); uint len = length(); if ( bl == al ) { if ( bl ) { - while( (index = find( before, index ) ) != -1 ) { + while( (index = find( before, index, TRUE, len ) ) != -1 ) { memcpy( d+index, after, al ); index += bl; } } } else if ( al < bl ) { uint to = 0; uint movestart = 0; uint num = 0; - while( (index = find( before, index ) ) != -1 ) { + while( (index = find( before, index, TRUE, len ) ) != -1 ) { if ( num ) { int msize = index - movestart; if ( msize > 0 ) { memmove( d + to, d + movestart, msize ); to += msize; } @@ -1683,13 +1720,13 @@ QCString &QCString::replace( const char *before, const char *after ) // the most complex case. We don't want to loose performance by doing repeated // copies and reallocs of the string. while( index != -1 ) { uint indices[4096]; uint pos = 0; while( pos < 4095 ) { - index = find(before, index); + index = find(before, index, TRUE, len); if ( index == -1 ) break; indices[pos++] = index; index += bl; // avoid infinite loop if ( !bl ) @@ -1760,13 +1797,13 @@ QCString &QCString::replace( char c1, char c2 ) string it is more efficient to convert the string to a QString and apply the function to that. */ int QCString::find( const QRegExp& rx, int index ) const { - QString d = QString::fromLatin1( data() ); + QString d = QString::fromAscii( data() ); return d.find( rx, index ); } /*! \overload @@ -1780,13 +1817,13 @@ int QCString::find( const QRegExp& rx, int index ) const string it is more efficient to convert the string to a QString and apply the function to that. */ int QCString::findRev( const QRegExp& rx, int index ) const { - QString d = QString::fromLatin1( data() ); + QString d = QString::fromAscii( data() ); return d.findRev( rx, index ); } /*! \overload @@ -1805,13 +1842,13 @@ int QCString::findRev( const QRegExp& rx, int index ) const string it is more efficient to convert the string to a QString and apply the function to that. */ int QCString::contains( const QRegExp &rx ) const { - QString d = QString::fromLatin1( data() ); + QString d = QString::fromAscii( data() ); return d.contains( rx ); } /*! \overload @@ -1835,14 +1872,14 @@ int QCString::contains( const QRegExp &rx ) const string it is more efficient to convert the string to a QString and apply the function to that. */ QCString &QCString::replace( const QRegExp &rx, const char *str ) { - QString d = QString::fromLatin1( data() ); - QString r = QString::fromLatin1( str ); + QString d = QString::fromAscii( data() ); + QString r = QString::fromAscii( str ); d.replace( rx, r ); setStr( d.ascii() ); return *this; } #endif //QT_NO_REGEXP @@ -2196,13 +2233,13 @@ QCString& QCString::operator+=( const char *str ) { if ( !str ) return *this; // nothing to append detach(); uint len1 = length(); uint len2 = qstrlen(str); - if ( !QByteArray::resize( len1 + len2 + 1 ) ) + if ( !QByteArray::resize( len1 + len2 + 1, QByteArray::SpeedOptim ) ) return *this; // no memory memcpy( data() + len1, str, len2 + 1 ); return *this; } /*! @@ -2212,13 +2249,13 @@ QCString& QCString::operator+=( const char *str ) */ QCString &QCString::operator+=( char c ) { detach(); uint len = length(); - if ( !QByteArray::resize( len + 2 ) ) + if ( !QByteArray::resize( len + 2, QByteArray::SpeedOptim ) ) return *this; // no memory *(data() + len) = c; *(data() + len+1) = '\0'; return *this; } diff --git a/qmake/tools/qdatastream.cpp b/qmake/tools/qdatastream.cpp index 9c573c7..51a1448 100644 --- a/qmake/tools/qdatastream.cpp +++ b/qmake/tools/qdatastream.cpp @@ -747,14 +747,22 @@ QDataStream &QDataStream::readBytes( char *&s, uint &l ) QDataStream &QDataStream::readRawBytes( char *s, uint len ) { CHECK_STREAM_PRECOND if ( printable ) { // printable data register Q_INT8 *p = (Q_INT8*)s; - while ( len-- ) - *this >> *p++; + if ( version() < 4 ) { + while ( len-- ) { + Q_INT32 tmp; + *this >> tmp; + *p++ = tmp; + } + } else { + while ( len-- ) + *this >> *p++; + } } else { // read data char array dev->readBlock( s, len ); } return *this; } @@ -1009,15 +1017,21 @@ QDataStream &QDataStream::writeBytes(const char *s, uint len) */ QDataStream &QDataStream::writeRawBytes( const char *s, uint len ) { CHECK_STREAM_PRECOND if ( printable ) { // write printable - register Q_INT8 *p = (Q_INT8*)s; - while ( len-- ) - *this << *p++; + if ( version() < 4 ) { + register char *p = (char *)s; + while ( len-- ) + *this << *p++; + } else { + register Q_INT8 *p = (Q_INT8*)s; + while ( len-- ) + *this << *p++; + } } else { // write data char array dev->writeBlock( s, len ); } return *this; } diff --git a/qmake/tools/qdatetime.cpp b/qmake/tools/qdatetime.cpp index 93e40a8..3137877 100644 --- a/qmake/tools/qdatetime.cpp +++ b/qmake/tools/qdatetime.cpp @@ -2,13 +2,13 @@ ** $Id$ ** ** Implementation of date and time classes ** ** Created : 940124 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -32,13 +32,12 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -// Get the system specific includes and defines #include "qplatformdefs.h" #include "qdatetime.h" #include "qdatastream.h" #include "qregexp.h" @@ -892,12 +891,18 @@ QDate QDate::addMonths( int nmonths ) const QDate QDate::addYears( int nyears ) const { int y, m, d; julianToGregorian( jd, y, m, d ); y += nyears; + + QDate tmp(y,m,1); + + if( d > tmp.daysInMonth() ) + d = tmp.daysInMonth(); + QDate date(y, m, d); return date; } @@ -987,19 +992,31 @@ QDate QDate::currentDate( Qt::TimeSpec ts ) if ( ts == Qt::LocalTime ) GetLocalTime( &t ); else GetSystemTime( &t ); d.jd = gregorianToJulian( t.wYear, t.wMonth, t.wDay ); #else + // posix compliant system time_t ltime; time( <ime ); tm *t; + +# if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // use the reentrant versions of localtime() and gmtime() where available + tm res; + if ( ts == Qt::LocalTime ) + t = localtime_r( <ime, &res ); + else + t = gmtime_r( <ime, &res ); +# else if ( ts == Qt::LocalTime ) t = localtime( <ime ); - else + else t = gmtime( <ime ); +# endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS + d.jd = gregorianToJulian( t->tm_year + 1900, t->tm_mon + 1, t->tm_mday ); #endif return d; } #ifndef QT_NO_DATESTRING @@ -1552,13 +1569,13 @@ int QTime::msecsTo( const QTime &t ) const Returns TRUE if this time is later than or equal to \a t; otherwise returns FALSE. */ -/*! +/*! \overload Returns the current time as reported by the system clock. Note that the accuracy depends on the accuracy of the underlying operating system; not all systems provide 1-millisecond accuracy. @@ -1650,28 +1667,39 @@ bool QTime::currentTime( QTime *ct, Qt::TimeSpec ts ) } else { GetSystemTime( &t ); } ct->ds = (uint)( MSECS_PER_HOUR*t.wHour + MSECS_PER_MIN*t.wMinute + 1000*t.wSecond + t.wMilliseconds ); #elif defined(Q_OS_UNIX) + // posix compliant system struct timeval tv; gettimeofday( &tv, 0 ); time_t ltime = tv.tv_sec; tm *t; - if ( ts == Qt::LocalTime ) { + +# if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // use the reentrant versions of localtime() and gmtime() where available + tm res; + if ( ts == Qt::LocalTime ) + t = localtime_r( <ime, &res ); + else + t = gmtime_r( <ime, &res ); +# else + if ( ts == Qt::LocalTime ) t = localtime( <ime ); - } else { + else t = gmtime( <ime ); - } +# endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS + ct->ds = (uint)( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec + tv.tv_usec / 1000 ); #else time_t ltime; // no millisecond resolution ::time( <ime ); tm *t; - if ( ts == Qt::LocalTime ) + if ( ts == Qt::LocalTime ) localtime( <ime ); else gmtime( <ime ); ct->ds = (uint) ( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec ); #endif @@ -1703,15 +1731,15 @@ bool QTime::isValid( int h, int m, int s, int ms ) /*! Sets this time to the current time. This is practical for timing: \code QTime t; - t.start(); // start clock - ... // some lengthy task - qDebug( "%d\n", t.elapsed() ); // prints the number of msecs elapsed + t.start(); + some_lengthy_task(); + qDebug( "Time elapsed: %d ms", t.elapsed() ); \endcode \sa restart(), elapsed(), currentTime() */ void QTime::start() @@ -1957,22 +1985,40 @@ void QDateTime::setTime_t( uint secsSince1Jan1970UTC ) \sa toTime_t() */ void QDateTime::setTime_t( uint secsSince1Jan1970UTC, Qt::TimeSpec ts ) { time_t tmp = (time_t) secsSince1Jan1970UTC; tm *brokenDown = 0; + +#if defined(Q_OS_UNIX) && defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // posix compliant system + // use the reentrant versions of localtime() and gmtime() where available + tm res; + if ( ts == Qt::LocalTime ) + brokenDown = localtime_r( &tmp, &res ); + if ( !brokenDown ) { + brokenDown = gmtime_r( &tmp, &res ); + if ( !brokenDown ) { + d.jd = QDate::gregorianToJulian( 1970, 1, 1 ); + t.ds = 0; + return; + } + } +#else if ( ts == Qt::LocalTime ) brokenDown = localtime( &tmp ); if ( !brokenDown ) { brokenDown = gmtime( &tmp ); if ( !brokenDown ) { d.jd = QDate::gregorianToJulian( 1970, 1, 1 ); t.ds = 0; return; } } +#endif + d.jd = QDate::gregorianToJulian( brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday ); t.ds = MSECS_PER_HOUR * brokenDown->tm_hour + MSECS_PER_MIN * brokenDown->tm_min + 1000 * brokenDown->tm_sec; @@ -2297,13 +2343,13 @@ bool QDateTime::operator>=( const QDateTime &dt ) const return TRUE; return d == dt.d ? t >= dt.t : FALSE; } /*! \overload - + Returns the current datetime, as reported by the system clock. \sa QDate::currentDate(), QTime::currentTime() */ QDateTime QDateTime::currentDateTime() diff --git a/qmake/tools/qdir.cpp b/qmake/tools/qdir.cpp index 418ea49..5714878 100644 --- a/qmake/tools/qdir.cpp +++ b/qmake/tools/qdir.cpp @@ -2,13 +2,13 @@ ** $Id$ ** ** Implementation of QDir class ** ** Created : 950427 ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -40,19 +40,24 @@ #ifndef QT_NO_DIR #include <private/qdir_p.h> #include "qfileinfo.h" #include "qregexp.h" #include "qstringlist.h" -#include <stdlib.h> -#include <ctype.h> +#include <limits.h> +#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX) +const bool CaseSensitiveFS = FALSE; +#else +const bool CaseSensitiveFS = TRUE; +#endif /*! \class QDir + \reentrant \brief The QDir class provides access to directory structures and their contents in a platform-independent way. \ingroup io \mainclass A QDir is used to manipulate path names, access information @@ -227,12 +232,20 @@ QDir::QDir( const QDir &d ) dirty = TRUE; allDirs = d.allDirs; filtS = d.filtS; sortS = d.sortS; } +/*! + Refreshes the directory information. +*/ +void QDir::refresh() const +{ + QDir* that = (QDir*) this; + that->dirty = TRUE; +} void QDir::init() { fList = 0; fiList = 0; nameFilt = QString::fromLatin1("*"); @@ -379,16 +392,42 @@ QString QDir::absFilePath( const QString &fileName, bool acceptAbsPath ) const { if ( acceptAbsPath && !isRelativePath( fileName ) ) return fileName; QString tmp = absPath(); - if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName && - fileName[0] != '/') ) - tmp += '/'; - tmp += fileName; +#ifdef Q_OS_WIN32 + if ( fileName[0].isLetter() && fileName[1] == ':' ) { + int drv = fileName.upper()[0].latin1() - 'A' + 1; + if ( _getdrive() != drv ) { + if ( qt_winunicode ) { + TCHAR buf[PATH_MAX]; + ::_tgetdcwd( drv, buf, PATH_MAX ); + tmp.setUnicodeCodes( (ushort*)buf, ::_tcslen(buf) ); + } else { + char buf[PATH_MAX]; + ::_getdcwd( drv, buf, PATH_MAX ); + tmp = buf; + } + if ( !tmp.endsWith("\\") ) + tmp += "\\"; + tmp += fileName.right( fileName.length() - 2 ); + int x; + for ( x = 0; x < (int) tmp.length(); x++ ) { + if ( tmp[x] == '\\' ) + tmp[x] = '/'; + } + } + } else +#endif + { + if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName && + fileName[0] != '/') ) + tmp += '/'; + tmp += fileName; + } return tmp; } /*! Returns \a pathName with the '/' separators converted to @@ -931,13 +970,14 @@ QDir &QDir::operator=( const QString &path ) Example: \code // The current directory is "/usr/local" QDir d1( "/usr/local/bin" ); QDir d2( "bin" ); - if ( d1 != d2 ) qDebug( "They differ\n" ); // This is printed + if ( d1 != d2 ) + qDebug( "They differ" ); \endcode */ /*! Returns TRUE if directory \a d and this directory have the same path and their sort and filter settings are the same; otherwise @@ -946,13 +986,14 @@ QDir &QDir::operator=( const QString &path ) Example: \code // The current directory is "/usr/local" QDir d1( "/usr/local/bin" ); QDir d2( "bin" ); d2.convertToAbs(); - if ( d1 == d2 ) qDebug( "They're the same\n" ); // This is printed + if ( d1 == d2 ) + qDebug( "They're the same" ); \endcode */ bool QDir::operator==( const QDir &d ) const { return dPath == d.dPath && @@ -1084,33 +1125,45 @@ QDir QDir::root() Returns the absolute path of the user's home directory. \sa home() */ -QStringList qt_makeFilterList( const QString &filter ) +QValueList<QRegExp> qt_makeFilterList( const QString &filter ) { + QValueList<QRegExp> regExps; if ( filter.isEmpty() ) - return QStringList(); + return regExps; QChar sep( ';' ); int i = filter.find( sep, 0 ); if ( i == -1 && filter.find( ' ', 0 ) != -1 ) sep = QChar( ' ' ); QStringList list = QStringList::split( sep, filter ); QStringList::Iterator it = list.begin(); - QStringList list2; + while ( it != list.end() ) { + regExps << QRegExp( (*it).stripWhiteSpace(), CaseSensitiveFS, TRUE ); + ++it; + } + return regExps; +} - for ( ; it != list.end(); ++it ) { - QString s = *it; - list2 << s.stripWhiteSpace(); +bool qt_matchFilterList( const QValueList<QRegExp>& filters, + const QString &fileName ) +{ + QValueList<QRegExp>::ConstIterator rit = filters.begin(); + while ( rit != filters.end() ) { + if ( (*rit).exactMatch(fileName) ) + return TRUE; + ++rit; } - return list2; + return FALSE; } + /*! \overload Returns TRUE if the \a fileName matches any of the wildcard (glob) patterns in the list of \a filters; otherwise returns FALSE. @@ -1120,17 +1173,13 @@ QStringList qt_makeFilterList( const QString &filter ) */ bool QDir::match( const QStringList &filters, const QString &fileName ) { QStringList::ConstIterator sit = filters.begin(); while ( sit != filters.end() ) { -#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX) - QRegExp rx( *sit, FALSE, TRUE ); // The FAT FS is not case sensitive.. -#else - QRegExp rx( *sit, TRUE, TRUE ); // ..while others are. -#endif + QRegExp rx( *sit, CaseSensitiveFS, TRUE ); if ( rx.exactMatch(fileName) ) return TRUE; ++sit; } return FALSE; } @@ -1144,14 +1193,13 @@ bool QDir::match( const QStringList &filters, const QString &fileName ) matching.\endlink) \sa QRegExp::match() */ bool QDir::match( const QString &filter, const QString &fileName ) { - QStringList lst = qt_makeFilterList( filter ); - return match( lst, fileName ); + return qt_matchFilterList( qt_makeFilterList(filter), fileName ); } /*! Removes all multiple directory separators "/" and resolves any "."s or ".."s found in the path, \a filePath. diff --git a/qmake/tools/qdir_unix.cpp b/qmake/tools/qdir_unix.cpp index 57fe3c5..6a7adda 100644 --- a/qmake/tools/qdir_unix.cpp +++ b/qmake/tools/qdir_unix.cpp @@ -2,13 +2,13 @@ ** $Id$ ** ** Implementation of QDir class ** ** Created : 950628 ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -48,12 +48,13 @@ #ifdef QT_THREAD_SUPPORT # include <private/qmutexpool_p.h> #endif // QT_THREAD_SUPPORT #include <stdlib.h> #include <limits.h> +#include <errno.h> void QDir::slashify( QString& ) { } @@ -67,38 +68,38 @@ QString QDir::homeDirPath() return d; } QString QDir::canonicalPath() const { QString r; - char cur[PATH_MAX+1]; - if ( ::getcwd( cur, PATH_MAX ) ) - if ( ::chdir(QFile::encodeName(dPath)) >= 0 ) { - char tmp[PATH_MAX+1]; - if ( ::getcwd( tmp, PATH_MAX ) ) - r = QFile::decodeName(tmp); - ::chdir( cur ); - } - - slashify( r ); + if ( ::getcwd( cur, PATH_MAX ) ) { + char tmp[PATH_MAX+1]; + if( ::realpath( QFile::encodeName( dPath ), tmp ) ) + r = QFile::decodeName( tmp ); + slashify( r ); + + // always make sure we go back to the current dir + ::chdir( cur ); + } return r; } bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const { #if defined(Q_OS_MACX) // Mac X doesn't support trailing /'s QString name = dirName; if (dirName[dirName.length() - 1] == "/") name = dirName.left( dirName.length() - 1 ); - return ::mkdir( QFile::encodeName(filePath(name,acceptAbsPath)), 0777 ) - == 0; + int status = + ::mkdir( QFile::encodeName(filePath(name,acceptAbsPath)), 0777 ); #else - return ::mkdir( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 ) - == 0; + int status = + ::mkdir( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 ); #endif + return status == 0; } bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const { return ::rmdir( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0; } @@ -183,40 +184,44 @@ bool QDir::readDirEntries( const QString &nameFilter, fiList->setAutoDelete( TRUE ); } else { fList->clear(); fiList->clear(); } - QStringList filters = qt_makeFilterList( nameFilter ); + QValueList<QRegExp> filters = qt_makeFilterList( nameFilter ); bool doDirs = (filterSpec & Dirs) != 0; bool doFiles = (filterSpec & Files) != 0; bool noSymLinks = (filterSpec & NoSymLinks) != 0; bool doReadable = (filterSpec & Readable) != 0; bool doWritable = (filterSpec & Writable) != 0; bool doExecable = (filterSpec & Executable) != 0; bool doHidden = (filterSpec & Hidden) != 0; bool doSystem = (filterSpec & System) != 0; -#if defined(Q_OS_OS2EMX) - //QRegExp wc( nameFilter, FALSE, TRUE ); // wild card, case insensitive -#else - //QRegExp wc( nameFilter, TRUE, TRUE ); // wild card, case sensitive -#endif QFileInfo fi; DIR *dir; dirent *file; dir = opendir( QFile::encodeName(dPath) ); if ( !dir ) return FALSE; // cannot read the directory - while ( (file = readdir(dir)) ) { +#if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) + union { + struct dirent mt_file; + char b[sizeof(struct dirent) + MAXNAMLEN + 1]; + } u; + while ( readdir_r(dir, &u.mt_file, &file ) == 0 && file ) +#else + while ( (file = readdir(dir)) ) +#endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS + { QString fn = QFile::decodeName(file->d_name); fi.setFile( *this, fn ); - if ( !match( filters, fn ) && !(allDirs && fi.isDir()) ) + if ( !qt_matchFilterList(filters, fn) && !(allDirs && fi.isDir()) ) continue; if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) || (doSystem && (!fi.isFile() && !fi.isDir())) ) { if ( noSymLinks && fi.isSymLink() ) continue; if ( (filterSpec & RWEMask) != 0 ) @@ -273,13 +278,14 @@ const QFileInfoList * QDir::drives() // points to that list static QFileInfoList * knownMemoryLeak = 0; if ( !knownMemoryLeak ) { #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &knownMemoryLeak ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &knownMemoryLeak ) : 0 ); #endif // QT_THREAD_SUPPORT if ( !knownMemoryLeak ) { knownMemoryLeak = new QFileInfoList; // non-win32 versions both use just one root directory knownMemoryLeak->append( new QFileInfo( rootDirPath() ) ); diff --git a/qmake/tools/qfile.cpp b/qmake/tools/qfile.cpp index a578b49..c088b55 100644 --- a/qmake/tools/qfile.cpp +++ b/qmake/tools/qfile.cpp @@ -85,13 +85,13 @@ extern bool qt_file_access( const QString& fn, int t ); QStringList lines; QFile file( "file.txt" ); if ( file.open( IO_ReadOnly ) ) { QTextStream stream( &file ); QString line; int i = 1; - while ( !stream.eof() ) { + while ( !stream.atEnd() ) { line = stream.readLine(); // line of text excluding '\n' printf( "%3d: %s\n", i++, line.latin1() ); lines += line; } file.close(); } @@ -287,12 +287,13 @@ void QFile::flush() /*! \reimp \fn QIODevice::Offset QFile::at() const */ /*! Returns TRUE if the end of file has been reached; otherwise returns FALSE. + If QFile has not been open()'d, then the behavior is undefined. \sa size() */ bool QFile::atEnd() const { diff --git a/qmake/tools/qfile_unix.cpp b/qmake/tools/qfile_unix.cpp index 2d5a856..460bf06 100644 --- a/qmake/tools/qfile_unix.cpp +++ b/qmake/tools/qfile_unix.cpp @@ -432,17 +432,20 @@ bool QFile::open( int m, int f ) \sa at() */ QIODevice::Offset QFile::size() const { struct stat st; + int ret = 0; if ( isOpen() ) { - ::fstat( fh ? fileno(fh) : fd, &st ); + ret = ::fstat( fh ? fileno(fh) : fd, &st ); } else { - ::stat( QFile::encodeName(fn), &st ); + ret = ::stat( QFile::encodeName(fn), &st ); } + if ( ret == -1 ) + return 0; #if defined(QT_LARGEFILE_SUPPORT) && !defined(QT_ABI_64BITOFFSET) return (uint)st.st_size > UINT_MAX ? UINT_MAX : (QIODevice::Offset)st.st_size; #else return st.st_size; #endif } @@ -535,13 +538,13 @@ Q_LONG QFile::readBlock( char *p, Q_ULONG len ) #endif Q_ULONG nread = 0; // number of bytes read if ( !ungetchBuffer.isEmpty() ) { // need to add these to the returned string. uint l = ungetchBuffer.length(); while( nread < l ) { - *p = ungetchBuffer[ l - nread - 1 ]; + *p = ungetchBuffer.at( l - nread - 1 ); p++; nread++; } ungetchBuffer.truncate( l - nread ); } @@ -626,13 +629,15 @@ Q_LONG QFile::writeBlock( const char *p, Q_ULONG len ) } /*! Returns the file handle of the file. This is a small positive integer, suitable for use with C library - functions such as fdopen() and fcntl(), as well as with QSocketNotifier. + functions such as fdopen() and fcntl(). On systems that use file + descriptors for sockets (ie. Unix systems, but not Windows) the handle + can be used with QSocketNotifier as well. If the file is not open or there is an error, handle() returns -1. \sa QSocketNotifier */ diff --git a/qmake/tools/qfileinfo.cpp b/qmake/tools/qfileinfo.cpp index 3af7932..a78f4fa 100644 --- a/qmake/tools/qfileinfo.cpp +++ b/qmake/tools/qfileinfo.cpp @@ -632,22 +632,24 @@ QDateTime QFileInfo::lastRead() const drive letter, except for network shares that are not mapped to a drive letter, in which case the path will begin '//sharename/'. This function returns the same as filePath(), unless isRelative() is TRUE. + If the QFileInfo is empty it returns QDir::currentDirPath(). + This function can be time consuming under Unix (in the order of milliseconds). \sa isRelative(), filePath() */ QString QFileInfo::absFilePath() const { QString tmp; if ( QDir::isRelativePath(fn) -#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) +#if defined(Q_OS_WIN32) && fn[1] != ':' #endif ) { tmp = QDir::currentDirPath(); tmp += '/'; } diff --git a/qmake/tools/qfileinfo_unix.cpp b/qmake/tools/qfileinfo_unix.cpp index f7c3a97..364f219 100644 --- a/qmake/tools/qfileinfo_unix.cpp +++ b/qmake/tools/qfileinfo_unix.cpp @@ -211,15 +211,15 @@ uint QFileInfo::groupId() const always returns TRUE. Example: \code QFileInfo fi( "/tmp/archive.tar.gz" ); if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) ) - qWarning( "I can change the file; my group can read the file."); + qWarning( "I can change the file; my group can read the file" ); if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) ) - qWarning( "The group or others can change the file!" ); + qWarning( "The group or others can change the file" ); \endcode \sa isReadable(), isWritable(), isExecutable() */ bool QFileInfo::permission( int permissionSpec ) const diff --git a/qmake/tools/qgarray.cpp b/qmake/tools/qgarray.cpp index 45c45ce..0a522e4 100644 --- a/qmake/tools/qgarray.cpp +++ b/qmake/tools/qgarray.cpp @@ -32,27 +32,37 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#include "qglobal.h" // needed to define Q_WS_WIN -#ifdef Q_WS_WIN -#include "qt_windows.h" // needed for bsearch on some platforms +#include "qglobal.h" +#if defined(Q_CC_BOR) + // needed for qsort() because of a std namespace problem on Borland +# include "qplatformdefs.h" +#elif defined(Q_WS_WIN) + // needed for bsearch on some platforms +# include "qt_windows.h" #endif #define QGARRAY_CPP #include "qgarray.h" #include <stdlib.h> #include <string.h> #ifdef QT_THREAD_SUPPORT # include <private/qmutexpool_p.h> #endif // QT_THREAD_SUPPORT -#define USE_MALLOC // comment to use new/delete +/* + If USE_MALLOC isn't defined, we use new[] and delete[] to allocate + memory. The documentation for QMemArray<T>::assign() explicitly + mentions that the array is freed using free(), so don't mess around + with USE_MALLOC unless you know what you're doing. +*/ +#define USE_MALLOC #undef NEW #undef DELETE #if defined(USE_MALLOC) #define NEW(type,size) ((type*)malloc(size*sizeof(type))) @@ -132,13 +142,17 @@ QGArray::QGArray( int size ) shd = newData(); Q_CHECK_PTR( shd ); if ( size == 0 ) // zero length return; shd->data = NEW(char,size); Q_CHECK_PTR( shd->data ); - shd->len = size; + shd->len = +#ifdef QT_QGARRAY_SPEED_OPTIM + shd->maxl = +#endif + size; } /*! Constructs a shallow copy of \a a. */ @@ -209,41 +223,76 @@ bool QGArray::isEqual( const QGArray &a ) const return TRUE; return (size() ? memcmp( data(), a.data(), size() ) : 0) == 0; } /*! - Resizes the array to \a newsize bytes. + Resizes the array to \a newsize bytes. \a optim is either + MemOptim (the default) or SpeedOptim. */ - -bool QGArray::resize( uint newsize ) +bool QGArray::resize( uint newsize, Optimization optim ) { - if ( newsize == shd->len ) // nothing to do +#ifndef QT_QGARRAY_SPEED_OPTIM + Q_UNUSED(optim); +#endif + + if ( newsize == shd->len +#ifdef QT_QGARRAY_SPEED_OPTIM + && newsize == shd->maxl +#endif + ) // nothing to do return TRUE; if ( newsize == 0 ) { // remove array duplicate( 0, 0 ); return TRUE; } + + uint newmaxl = newsize; +#ifdef QT_QGARRAY_SPEED_OPTIM + if ( optim == SpeedOptim ) { + if ( newsize <= shd->maxl && + ( newsize * 4 > shd->maxl || shd->maxl <= 4 ) ) { + shd->len = newsize; + return TRUE; + } + newmaxl = 4; + while ( newmaxl < newsize ) + newmaxl *= 2; + // try to spare some memory + if ( newmaxl >= 1024 * 1024 && newsize <= newmaxl - (newmaxl >> 2) ) + newmaxl -= newmaxl >> 2; + } + shd->maxl = newmaxl; +#endif + if ( shd->data ) { // existing data #if defined(DONT_USE_REALLOC) char *newdata = NEW(char,newsize); // manual realloc - memcpy( newdata, shd->data, QMIN(shd->len,newsize) ); + memcpy( newdata, shd->data, QMIN(shd->len,newmaxl) ); DELETE(shd->data); shd->data = newdata; #else - shd->data = (char *)realloc( shd->data, newsize ); + shd->data = (char *)realloc( shd->data, newmaxl ); #endif } else { - shd->data = NEW(char,newsize); + shd->data = NEW(char,newmaxl); } if ( !shd->data ) // no memory return FALSE; shd->len = newsize; return TRUE; } +/*!\overload +*/ +bool QGArray::resize( uint newsize ) +{ + return resize( newsize, MemOptim ); +} + + /*! Fills the array with the repeated occurrences of \a d, which is \a sz bytes long. If \a len is specified as different from -1, then the array will be resized to \a len*sz before it is filled. @@ -316,13 +365,17 @@ QGArray &QGArray::assign( const char *d, uint len ) Q_CHECK_PTR( shd ); } else { if ( shd->data ) DELETE(shd->data); } shd->data = (char *)d; - shd->len = len; + shd->len = +#ifdef QT_QGARRAY_SPEED_OPTIM + shd->maxl = +#endif + len; return *this; } /*! Deep copy. Dereference the current array and obtains a copy of the data contained in \a a instead. Returns a reference to this array. @@ -361,13 +414,17 @@ QGArray &QGArray::duplicate( const QGArray &a ) Q_CHECK_PTR( shd->data ); if ( shd->data ) memcpy( shd->data, a.shd->data, a.shd->len ); } else { shd->data = 0; } - shd->len = a.shd->len; + shd->len = +#ifdef QT_QGARRAY_SPEED_OPTIM + shd->maxl = +#endif + a.shd->len; if ( oldptr ) DELETE(oldptr); return *this; } /*! @@ -399,13 +456,17 @@ QGArray &QGArray::duplicate( const char *d, uint len ) Q_CHECK_PTR( shd ); } else { // just a single reference if ( shd->data ) DELETE(shd->data); } shd->data = data; - shd->len = len; + shd->len = +#ifdef QT_QGARRAY_SPEED_OPTIM + shd->maxl = +#endif + len; return *this; } /*! Resizes this array to \a len bytes and copies the \a len bytes at address \a d into it. @@ -656,13 +717,14 @@ void QGArray::sort( uint sz ) { int numItems = size() / sz; if ( numItems < 2 ) return; #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &cmp_item_size ) : 0 ); #endif // QT_THREAD_SUPPORT cmp_item_size = sz; qsort( shd->data, numItems, sz, cmp_arr ); } @@ -674,13 +736,14 @@ int QGArray::bsearch( const char *d, uint sz ) const { int numItems = size() / sz; if ( !numItems ) return -1; #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &cmp_item_size ) : 0 ); #endif // QT_THREAD_SUPPORT cmp_item_size = sz; char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr ); if ( !r ) return -1; diff --git a/qmake/tools/qgdict.cpp b/qmake/tools/qgdict.cpp index c431ff8..3d49fc7 100644 --- a/qmake/tools/qgdict.cpp +++ b/qmake/tools/qgdict.cpp @@ -201,13 +201,16 @@ QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys ) init( len, kt, caseSensitive, copyKeys ); } void QGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys ) { - vec = new QBaseBucket *[vlen = len]; // allocate hash table + vlen = len; + if ( vlen == 0 ) + vlen = 17; + vec = new QBaseBucket *[vlen]; Q_CHECK_PTR( vec ); memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) ); numItems = 0; iterators = 0; // The caseSensitive and copyKey options don't make sense for // all dict types. diff --git a/qmake/tools/qglist.cpp b/qmake/tools/qglist.cpp index 155d585..bd27f8a 100644 --- a/qmake/tools/qglist.cpp +++ b/qmake/tools/qglist.cpp @@ -326,18 +326,14 @@ QLNode *QGList::locate( uint index ) curIndex = 0; } register QLNode *node; int distance = index - curIndex; // node distance to cur node bool forward; // direction to traverse - if ( index >= numNodes ) { -#if defined(QT_CHECK_RANGE) - qWarning( "QGList::locate: Index %d out of range", index ); -#endif + if ( index >= numNodes ) return 0; - } if ( distance < 0 ) distance = -distance; if ( (uint)distance < index && (uint)distance < numNodes - index ) { node = curNode; // start from current node forward = index > (uint)curIndex; diff --git a/qmake/tools/qglobal.cpp b/qmake/tools/qglobal.cpp index 47cd6bd..342005d 100644 --- a/qmake/tools/qglobal.cpp +++ b/qmake/tools/qglobal.cpp @@ -146,13 +146,34 @@ bool qSysInfo( int *wordSize, bool *bigEndian ) *bigEndian = si_bigEndian = be32; si_alreadyDone = TRUE; return TRUE; } -#if defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN) +#if !defined(QWS) && defined(Q_OS_MAC) + +#include "qt_mac.h" + +int qMacVersion() +{ + static int macver = Qt::MV_Unknown; + static bool first = TRUE; + if(first) { + first = FALSE; + long gestalt_version; + if(Gestalt(gestaltSystemVersion, &gestalt_version) == noErr) { + if(gestalt_version >= 0x1020 && gestalt_version < 0x1030) + macver = Qt::MV_10_DOT_2; + else if(gestalt_version >= 0x1010 && gestalt_version < 0x1020) + macver = Qt::MV_10_DOT_1; + } + } + return macver; +} +Qt::MacintoshVersion qt_macver = (Qt::MacintoshVersion)qMacVersion(); +#elif defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN) bool qt_winunicode; #include "qt_windows.h" int qWinVersion() { @@ -318,13 +339,25 @@ Qt::WindowsVersion qt_winver = (Qt::WindowsVersion)qWinVersion(); static QtMsgHandler handler = 0; // pointer to debug handler static const int QT_BUFFER_LENGTH = 8196; // internal buffer length #ifdef Q_OS_MAC -const unsigned char * p_str(const char * c, int len=-1) +QString cfstring2qstring(CFStringRef str) +{ + CFIndex length = CFStringGetLength(str); + if(const UniChar *chars = CFStringGetCharactersPtr(str)) + return QString((QChar *)chars, length); + UniChar *buffer = (UniChar*)malloc(length * sizeof(UniChar)); + CFStringGetCharacters(str, CFRangeMake(0, length), buffer); + QString ret((QChar *)buffer, length); + free(buffer); + return ret; +} + +unsigned char * p_str(const char * c, int len=-1) { const int maxlen = 255; if(len == -1) len = qstrlen(c); if(len > maxlen) { qWarning( "p_str len must never exceed %d", maxlen ); @@ -334,13 +367,13 @@ const unsigned char * p_str(const char * c, int len=-1) *ret=len; memcpy(((char *)ret)+1,c,len); *(ret+len+1) = '\0'; return ret; } -const unsigned char * p_str(const QString &s) +unsigned char * p_str(const QString &s) { return p_str(s, s.length()); } QCString p2qstring(const unsigned char *c) { char *arr = (char *)malloc(c[0] + 1); @@ -638,24 +671,24 @@ void qSystemWarning( const char* msg, int code ) /*! \fn void Q_CHECK_PTR( void *p ) \relates QApplication - If \a p is null, a fatal messages says that the program ran out of - memory and exits. If \e p is not null, nothing happens. + If \a p is 0, a fatal messages says that the program ran out of + memory and exits. If \e p is not 0, nothing happens. This is really a macro defined in \c qglobal.h. Example: \code int *a; Q_CHECK_PTR( a = new int[80] ); // WRONG! - a = new int[80]; // Right + a = new (nothrow) int[80]; // Right Q_CHECK_PTR( a ); \endcode \sa qFatal(), \link debug.html Debugging\endlink */ diff --git a/qmake/tools/qgpluginmanager.cpp b/qmake/tools/qgpluginmanager.cpp index 46c85f5..72246ac 100644 --- a/qmake/tools/qgpluginmanager.cpp +++ b/qmake/tools/qgpluginmanager.cpp @@ -1,12 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Implementation of QGPluginManager class ** -** Copyright (C) 2000-2001 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2003 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -472,13 +472,13 @@ bool QGPluginManager::addLibrary( QLibrary* lib ) if ( fliFace ) // Map all found features to the library fl = fliFace->featureList(); else if ( cpiFace ) fl << cpiFace->name(); - for ( QStringList::Iterator f = fl.begin(); f != fl.end(); f++ ) { + for ( QStringList::Iterator f = fl.begin(); f != fl.end(); ++f ) { QLibrary *old = plugDict[*f]; if ( !old ) { useful = TRUE; plugDict.replace( *f, plugin ); } else { // we have old *and* plugin, which one to pick? diff --git a/qmake/tools/qgvector.cpp b/qmake/tools/qgvector.cpp index 1985f03..3c903ed 100644 --- a/qmake/tools/qgvector.cpp +++ b/qmake/tools/qgvector.cpp @@ -32,12 +32,18 @@ ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ +#include "qglobal.h" +#if defined(Q_CC_BOR) +// needed for qsort() because of a std namespace problem on Borland +#include "qplatformdefs.h" +#endif + #define QGVECTOR_CPP #include "qgvector.h" #include "qglist.h" #include "qstring.h" #include "qdatastream.h" #include <stdlib.h> @@ -390,13 +396,14 @@ void QGVector::sort() // sort vector } else { break; } } #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &sort_vec ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &sort_vec ) : 0 ); #endif // QT_THREAD_SUPPORT sort_vec = (QGVector*)this; qsort( vec, count(), sizeof(Item), cmp_vec ); sort_vec = 0; } diff --git a/qmake/tools/qlibrary.cpp b/qmake/tools/qlibrary.cpp index 564db30..be1d54b 100644 --- a/qmake/tools/qlibrary.cpp +++ b/qmake/tools/qlibrary.cpp @@ -1,14 +1,14 @@ /**************************************************************************** ** $Id$ ** ** Implementation of QLibrary class ** -** Created : 2000-01-01 +** Created : 000101 ** -** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2003 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -68,13 +68,13 @@ QLibraryPrivate::QLibraryPrivate( QLibrary *lib ) /*! \class QLibrary qlibrary.h \reentrant \brief The QLibrary class provides a wrapper for handling shared libraries. \mainclass - \group plugins + \ingroup plugins An instance of a QLibrary object can handle a single shared library and provide access to the functionality in the library in a platform independent way. If the library is a component server, QLibrary provides access to the exported component and can directly query this component for interfaces. @@ -323,20 +323,21 @@ QString QLibrary::library() const if ( filename.findRev( '.' ) <= filename.findRev( '/' ) ) filename += ".dll"; #elif defined(Q_OS_MACX) if ( filename.find( ".dylib" ) == -1 ) filename += ".dylib"; #else - if ( filename.find( ".so" ) == -1 ) { + QString filter = ".so"; + if ( filename.find(filter) == -1 ) { const int x = filename.findRev( "/" ); if ( x != -1 ) { QString path = filename.left( x + 1 ); QString file = filename.right( filename.length() - x - 1 ); - filename = QString( "%1lib%2.so" ).arg( path ).arg( file ); + filename = QString( "%1lib%2.%3" ).arg( path ).arg( file ).arg( filter ); } else { - filename = QString( "lib%1.so" ).arg( filename ); + filename = QString( "lib%1.%2" ).arg( filename ).arg( filter ); } } #endif return filename; } diff --git a/qmake/tools/qlibrary_unix.cpp b/qmake/tools/qlibrary_unix.cpp index f0fbdf6..12b9310 100644 --- a/qmake/tools/qlibrary_unix.cpp +++ b/qmake/tools/qlibrary_unix.cpp @@ -1,12 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Implementation of QLibraryPrivate class ** -** Created : 2000-01-01 +** Created : 000101 ** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License @@ -50,13 +50,30 @@ - freeLibrary - resolveSymbol It's not too hard to guess what the functions do. */ -#if defined(QT_HPUX_LD) // for HP-UX < 11.x and 32 bit +#if defined(Q_OS_MAC) + +bool QLibraryPrivate::loadLibrary() +{ + return FALSE; +} + +bool QLibraryPrivate::freeLibrary() +{ + return FALSE; +} + +void* QLibraryPrivate::resolveSymbol( const char* ) +{ + return 0; +} + +#elif defined(QT_HPUX_LD) // for HP-UX < 11.x and 32 bit bool QLibraryPrivate::loadLibrary() { if ( pHnd ) return TRUE; diff --git a/qmake/tools/qmutex_unix.cpp b/qmake/tools/qmutex_unix.cpp index c861b2d..3eb59cf 100644 --- a/qmake/tools/qmutex_unix.cpp +++ b/qmake/tools/qmutex_unix.cpp @@ -40,14 +40,15 @@ #include "qplatformdefs.h" typedef pthread_mutex_t Q_MUTEX_T; // POSIX threads mutex types #if ((defined(PTHREAD_MUTEX_RECURSIVE) && defined(PTHREAD_MUTEX_DEFAULT)) || \ - defined(Q_OS_FREEBSD)) && !defined(Q_OS_UNIXWARE) && !defined(Q_OS_SOLARIS) - // POSIX 1003.1c-1995 - We love this OS + defined(Q_OS_FREEBSD)) && !defined(Q_OS_UNIXWARE) && !defined(Q_OS_SOLARIS) && \ + !defined(Q_OS_MAC) +// POSIX 1003.1c-1995 - We love this OS # define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_settype((a), (b)) # if defined(QT_CHECK_RANGE) # define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK # else # define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT # endif @@ -658,13 +659,14 @@ bool QMutex::tryLock() */ /*! \fn QMutexLocker::QMutexLocker( QMutex *mutex ) Constructs a QMutexLocker and locks \a mutex. The mutex will be - unlocked when the QMutexLocker is destroyed. + unlocked when the QMutexLocker is destroyed. If \a mutex is zero, + QMutexLocker does nothing. \sa QMutex::lock() */ /*! \fn QMutexLocker::~QMutexLocker() diff --git a/qmake/tools/qmutexpool.cpp b/qmake/tools/qmutexpool.cpp index 9ed2829..a8e7402 100644 --- a/qmake/tools/qmutexpool.cpp +++ b/qmake/tools/qmutexpool.cpp @@ -1,30 +1,49 @@ +/**************************************************************************** +** $Id$ +** +** ... +** +** Copyright (C) 2002 Trolltech AS. All rights reserved. +** +** This file is part of the tools module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + #include "qmutexpool_p.h" #ifdef QT_THREAD_SUPPORT #include <qthread.h> -#include <stdio.h> QMutexPool *qt_global_mutexpool = 0; -// this is an internal class used only for inititalizing the global mutexpool -class QGlobalMutexPoolInitializer -{ -public: - inline QGlobalMutexPoolInitializer() - { - /* - Purify will report a leak here. However, this mutex pool must be alive - until *everything* in Qt has been destructed. Unfortunately there is - no way to guarantee this, so we never destroy this mutex pool. - */ - qt_global_mutexpool = new QMutexPool( TRUE ); - } -}; -QGlobalMutexPoolInitializer qt_global_mutexpool_initializer; /*! \class QMutexPool qmutexpool_p.h \brief The QMutexPool class provides a pool of QMutex objects. \internal @@ -82,49 +101,52 @@ QGlobalMutexPoolInitializer qt_global_mutexpool_initializer; mutexes; otherwise they will all be non-recursive (the default). The QMutexes are created when needed, and deleted when the QMutexPool is destructed. */ QMutexPool::QMutexPool( bool recursive, int size ) - : mutex( FALSE ), mutexes( size ), recurs( recursive ) + : mutex( FALSE ), count( size ), recurs( recursive ) { - mutexes.fill( 0 ); + mutexes = new QMutex*[count]; + for ( int index = 0; index < count; ++index ) { + mutexes[index] = 0; + } } /*! Destructs a QMutexPool. All QMutexes that were created by the pool are deleted. */ QMutexPool::~QMutexPool() { QMutexLocker locker( &mutex ); - QMutex **d = mutexes.data(); - for ( int index = 0; (uint) index < mutexes.size(); index++ ) { - delete d[index]; - d[index] = 0; + for ( int index = 0; index < count; ++index ) { + delete mutexes[index]; + mutexes[index] = 0; } + delete [] mutexes; + mutexes = 0; } /*! Returns a QMutex from the pool. QMutexPool uses the value \a address to determine which mutex is retured from the pool. */ QMutex *QMutexPool::get( void *address ) { - QMutex **d = mutexes.data(); - int index = (int)( (ulong) address % mutexes.size() ); + int index = (int) ( (unsigned long) address % count ); - if ( ! d[index] ) { + if ( ! mutexes[index] ) { // mutex not created, create one QMutexLocker locker( &mutex ); // we need to check once again that the mutex hasn't been created, since // 2 threads could be trying to create a mutex as the same index... - if ( ! d[index] ) { - d[index] = new QMutex( recurs ); + if ( ! mutexes[index] ) { + mutexes[index] = new QMutex( recurs ); } } - return d[index]; + return mutexes[index]; } #endif diff --git a/qmake/tools/qregexp.cpp b/qmake/tools/qregexp.cpp index 500efed..0c1f060 100644 --- a/qmake/tools/qregexp.cpp +++ b/qmake/tools/qregexp.cpp @@ -260,21 +260,21 @@ hexadecimal number hhhh (between 0x0000 and 0xFFFF). \0ooo (i.e., \zero ooo) matches the ASCII/Latin-1 character corresponding to the octal number ooo (between 0 and 0377). \row \i <b>. (dot)</b> \i This matches any character (including newline). \row \i <b>\\d</b> - \i This matches a digit (see QChar::isDigit()). + \i This matches a digit (QChar::isDigit()). \row \i <b>\\D</b> \i This matches a non-digit. \row \i <b>\\s</b> - \i This matches a whitespace (see QChar::isSpace()). + \i This matches a whitespace (QChar::isSpace()). \row \i <b>\\S</b> \i This matches a non-whitespace. \row \i <b>\\w</b> - \i This matches a word character (see QChar::isLetterOrNumber()). + \i This matches a word character (QChar::isLetterOrNumber() or '_'). \row \i <b>\\W</b> \i This matches a non-word character. \row \i <b>\\n</b> \i The n-th \link #capturing-text backreference \endlink, e.g. \1, \2, etc. \endtable @@ -544,13 +544,20 @@ ... correspond to cap(1) or capturedTexts()[1], cap(2) or capturedTexts()[2], etc. To substitute a pattern use QString::replace(). Perl's extended \c{/x} syntax is not supported, nor are - regexp comments (?#comment) or directives, e.g. (?i). + directives, e.g. (?i), or regexp comments, e.g. (?#comment). On + the other hand, C++'s rules for literal strings can be used to + achieve the same: + \code + QRegExp mark( "\\b" // word boundary + "[Mm]ark" // the word we want to match + ); + \endcode Both zero-width positive and zero-width negative lookahead assertions (?=pattern) and (?!pattern) are supported with the same syntax as Perl. Perl's lookbehind assertions, "independent" subexpressions and conditional expressions are not supported. @@ -674,17 +681,17 @@ Here field[0] is the company, field[1] the web address and so on. To imitate the matching of a shell we can use wildcard mode. \code - QRegExp rx( "*.html" ); // invalid regexp: * doesn't quantify anything - rx.setWildcard( TRUE ); // now it's a valid wildcard regexp - rx.search( "index.html" ); // returns 0 (matched at position 0) - rx.search( "default.htm" ); // returns -1 (no match) - rx.search( "readme.txt" ); // returns -1 (no match) + QRegExp rx( "*.html" ); // invalid regexp: * doesn't quantify anything + rx.setWildcard( TRUE ); // now it's a valid wildcard regexp + rx.exactMatch( "index.html" ); // returns TRUE + rx.exactMatch( "default.htm" ); // returns FALSE + rx.exactMatch( "readme.txt" ); // returns FALSE \endcode Wildcard matching can be convenient because of its simplicity, but any wildcard regexp can be defined using full regexps, e.g. <b>.*\.html$</b>. Notice that we can't match both \c .html and \c .htm files with a wildcard unless we use <b>*.htm*</b> which will @@ -712,12 +719,17 @@ const int NumBadChars = 64; const int NoOccurrence = INT_MAX; const int EmptyCapture = INT_MAX; const int InftyLen = INT_MAX; const int InftyRep = 1025; const int EOS = -1; +static bool isWord( QChar ch ) +{ + return ch.isLetterOrNumber() || ch == QChar( '_' ); +} + /* Merges two QMemArrays of ints and puts the result into the first one. */ static void mergeInto( QMemArray<int> *a, const QMemArray<int>& b ) { int asize = a->size(); @@ -1677,15 +1689,15 @@ bool QRegExpEngine::testAnchor( int i, int a, const int *capBegin ) } #ifndef QT_NO_REGEXP_ESCAPE if ( (a & (Anchor_Word | Anchor_NonWord)) != 0 ) { bool before = FALSE; bool after = FALSE; if ( mmPos + i != 0 ) - before = mmIn[mmPos + i - 1].isLetterOrNumber(); + before = isWord( mmIn[mmPos + i - 1] ); if ( mmPos + i != mmLen ) - after = mmIn[mmPos + i].isLetterOrNumber(); + after = isWord( mmIn[mmPos + i] ); if ( (a & Anchor_Word) != 0 && (before == after) ) return FALSE; if ( (a & Anchor_NonWord) != 0 && (before != after) ) return FALSE; } #endif @@ -2629,13 +2641,20 @@ int QRegExpEngine::getEscape() yyCharClass->addRange( 0x0000, 0x0008 ); yyCharClass->addRange( 0x000e, 0x001f ); yyCharClass->addRange( 0x007f, 0x009f ); return Tok_CharClass; case 'W': // see QChar::isLetterOrNumber() - yyCharClass->addCategories( 0x7ff07f8f ); + yyCharClass->addCategories( 0x7fe07f8f ); + yyCharClass->addRange( 0x203f, 0x2040 ); + yyCharClass->addSingleton( 0x2040 ); + yyCharClass->addSingleton( 0x30fb ); + yyCharClass->addRange( 0xfe33, 0xfe34 ); + yyCharClass->addRange( 0xfe4d, 0xfe4f ); + yyCharClass->addSingleton( 0xff3f ); + yyCharClass->addSingleton( 0xff65 ); return Tok_CharClass; #endif #ifndef QT_NO_REGEXP_ESCAPE case 'b': return Tok_Word; #endif @@ -2649,12 +2668,13 @@ int QRegExpEngine::getEscape() yyCharClass->addCategories( 0x00000380 ); yyCharClass->addRange( 0x0009, 0x000d ); return Tok_CharClass; case 'w': // see QChar::isLetterOrNumber() yyCharClass->addCategories( 0x000f8070 ); + yyCharClass->addSingleton( 0x005f ); // '_' return Tok_CharClass; #endif #ifndef QT_NO_REGEXP_ESCAPE case 'x': val = 0; for ( i = 0; i < 4; i++ ) { @@ -3180,13 +3200,14 @@ static QSingleCleanupHandler<QCache<QRegExpEngine> > cleanup_cache; static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive ) { #ifndef QT_NO_REGEXP_OPTIM if ( engineCache != 0 ) { #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &engineCache ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &engineCache ) : 0 ); #endif QRegExpEngine *eng = engineCache->take( pattern ); if ( eng == 0 || eng->caseSensitive() != caseSensitive ) { delete eng; } else { eng->ref(); @@ -3196,17 +3217,18 @@ static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive ) #endif return new QRegExpEngine( pattern, caseSensitive ); } static void derefEngine( QRegExpEngine *eng, const QString& pattern ) { - if ( eng != 0 && eng->deref() ) { -#ifndef QT_NO_REGEXP_OPTIM #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &engineCache ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &engineCache ) : 0 ); #endif + if ( eng != 0 && eng->deref() ) { +#ifndef QT_NO_REGEXP_OPTIM if ( engineCache == 0 ) { engineCache = new QCache<QRegExpEngine>; engineCache->setAutoDelete( TRUE ); cleanup_cache.set( &engineCache ); } if ( !pattern.isNull() && @@ -3562,19 +3584,12 @@ int QRegExp::match( const QString& str, int index, int *len, if ( len != 0 ) *len = matchedLength(); return pos; } #endif // QT_NO_COMPAT -/*! - \overload - - This convenience function searches with a \c CaretMode of \c - CaretAtZero which is the most common usage. -*/ - int QRegExp::search( const QString& str, int offset ) const { return search( str, offset, CaretAtZero ); } /*! @@ -3622,19 +3637,12 @@ int QRegExp::search( const QString& str, int offset, CaretMode caretMode ) const priv->captured = eng->match( str, offset, priv->min, FALSE, caretIndex(offset, caretMode) ); return priv->captured[0]; } -/*! - \overload - - This convenience function searches with a \c CaretMode of \c - CaretAtZero which is the most common usage. -*/ - int QRegExp::searchRev( const QString& str, int offset ) const { return searchRev( str, offset, CaretAtZero ); } /*! @@ -3691,13 +3699,13 @@ int QRegExp::searchRev( const QString& str, int offset, int QRegExp::matchedLength() const { return priv->captured[1]; } #ifndef QT_NO_REGEXP_CAPTURE -/*! +/*! Returns the number of captures contained in the regular expression. */ int QRegExp::numCaptures() const { return eng->numCaptures(); } diff --git a/qmake/tools/qsemaphore_unix.cpp b/qmake/tools/qsemaphore_unix.cpp index fcf28da..4516049 100644 --- a/qmake/tools/qsemaphore_unix.cpp +++ b/qmake/tools/qsemaphore_unix.cpp @@ -180,24 +180,23 @@ int QSemaphore::operator--(int) int QSemaphore::operator+=(int n) { int ret; d->mutex.lock(); + if ( n < 0 || n > d->max ) { +#ifdef QT_CHECK_RANGE + qWarning( "QSemaphore::operator+=: paramter %d out of range", n ); +#endif // QT_CHECK_RANGE + n = n < 0 ? 0 : d->max; + } + while (d->value + n > d->max) d->cond.wait(&(d->mutex)); d->value += n; - -#ifdef QT_CHECK_RANGE - if (d->value > d->max) { - qWarning("QSemaphore::operator+=: attempt to allocate more resources than available"); - d->value = d->max; - } -#endif - ret = d->value; d->mutex.unlock(); return ret; } @@ -209,21 +208,20 @@ int QSemaphore::operator+=(int n) int QSemaphore::operator-=(int n) { int ret; d->mutex.lock(); - d->value -= n; - + if ( n < 0 || n > d->value ) { #ifdef QT_CHECK_RANGE - if (d->value < 0) { - qWarning("QSemaphore::operator-=: attempt to deallocate more resources than taken"); - d->value = 0; + qWarning( "QSemaphore::operator-=: paramter %d out of range", n ); +#endif // QT_CHECK_RANGE + n = n < 0 ? 0 : d->value; } -#endif + d->value -= n; ret = d->value; d->cond.wakeOne(); d->mutex.unlock(); return ret; diff --git a/qmake/tools/qsettings.cpp b/qmake/tools/qsettings.cpp index 5de105c..35fc039 100644 --- a/qmake/tools/qsettings.cpp +++ b/qmake/tools/qsettings.cpp @@ -1,12 +1,12 @@ /**************************************************************************** ** $Id$ ** ** Implementation of QSettings class ** -** Created: 2000.06.26 +** Created : 000626 ** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License @@ -60,35 +60,35 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) #include "qtextstream.h" #include "qregexp.h" #include <private/qsettings_p.h> #include <errno.h> /*! - \class QSettings - \brief The QSettings class provides persistent platform-independent application settings. - - \ingroup io - \ingroup misc - \mainclass - - On Unix systems, QSettings uses text files to store settings. On Windows - systems, QSettings uses the system registry. On Mac OS X, QSettings will - behave as on Unix, and store to text files. - - Each setting comprises an identifying key and the data associated with - the key. A key is a unicode string which consists of \e two or more - subkeys. A subkey is a slash, '/', followed by one or more unicode - characters (excluding slashes, newlines, carriage returns and equals, - '=', signs). The associated data, called the entry or value, may be a - boolean, an integer, a double, a string or a list of strings. Entry - strings may contain any unicode characters. - - If you want to save and restore the entire desktop's settings, i.e. - which applications are running, use QSettings to save the settings - for each individual application and QSessionManager to save the - desktop's session. + \class QSettings + \brief The QSettings class provides persistent platform-independent application settings. + + \ingroup io + \ingroup misc + \mainclass + + On Unix systems, QSettings uses text files to store settings. On Windows + systems, QSettings uses the system registry. On Mac OS X, QSettings uses + the Carbon preferences API. + + Each setting comprises an identifying key and the data associated with + the key. A key is a unicode string which consists of \e two or more + subkeys. A subkey is a slash, '/', followed by one or more unicode + characters (excluding slashes, newlines, carriage returns and equals, + '=', signs). The associated data, called the entry or value, may be a + boolean, an integer, a double, a string or a list of strings. Entry + strings may contain any unicode characters. + + If you want to save and restore the entire desktop's settings, i.e. + which applications are running, use QSettings to save the settings + for each individual application and QSessionManager to save the + desktop's session. Example settings: \code /MyCompany/MyApplication/background color /MyCompany/MyApplication/foreground color /MyCompany/MyApplication/geometry/x @@ -98,33 +98,48 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) /MyCompany/MyApplication/recent files/1 /MyCompany/MyApplication/recent files/2 /MyCompany/MyApplication/recent files/3 \endcode Each line above is a complete key, made up of subkeys. - A typical usage pattern for application startup: + A typical usage pattern for reading application startup: \code QSettings settings; - settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); - // No search path needed for Unix; see notes further on. - // Use default values if the keys don't exist - QString bgColor = settings.readEntry( "/MyApplication/background color", "white" ); - int width = settings.readNumEntry( "/MyApplication/geometry/width", 640 ); + settings.setPath( "MyCompany.com", "MyApplication" ); + + QString bgColor = settings.readEntry( "/colors/background", "white" ); + int width = settings.readNumEntry( "/geometry/width", 640 ); // ... \endcode A typical usage pattern for application exit or 'save preferences': \code QSettings settings; - settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); - // No search path needed for Unix; see notes further on. - settings.writeEntry( "/MyApplication/background color", bgColor ); - settings.writeEntry( "/MyApplication/geometry/width", width ); + settings.setPath( "MyCompany.com", "MyApplication" ); + + settings.writeEntry( "/colors/background", bgColor ); + settings.writeEntry( "/geometry/width", width ); // ... \endcode + QSettings can build a key prefix that is prepended to all keys. To + build the key prefix, use beginGroup() and endGroup(). + \code + QSettings settings; + + settings.beginGroup( "/MainWindow" ); + settings.beginGroup( "/Geometry" ); + int x = settings.readEntry( "/x" ); + // ... + settings.endGroup(); + settings.beginGroup( "/Toolbars" ); + // ... + settings.endGroup(); + settings.endGroup(); + \endcode + You can get a list of entry-holding keys by calling entryList(), and a list of key-holding keys using subkeyList(). \code QStringList keys = entryList( "/MyApplication" ); // keys contains 'background color' and 'foreground color'. @@ -136,26 +151,40 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) // subkeys contains 'geometry' and 'recent files' QStringList subkeys = subkeyList( "/MyApplication/recent files" ); // subkeys is empty. \endcode - If you wish to use a different search path call insertSearchPath() - as often as necessary to add your preferred paths. Call - removeSearchPath() to remove any unwanted paths. - Since settings for Windows are stored in the registry there are size limits as follows: \list \i A subkey may not exceed 255 characters. \i An entry's value may not exceed 16,300 characters. \i All the values of a key (for example, all the 'recent files' subkeys values), may not exceed 65,535 characters. \endlist - These limitations are not enforced on Unix. + These limitations are not enforced on Unix or Mac OS X. + + If you wish to use a different search path call insertSearchPath() + as often as necessary to add your preferred paths. Call + removeSearchPath() to remove any unwanted paths. + + \section1 Notes for Mac OS X Applications + + Internal to the CFPreferences API it is not defined (for Mac OS 9 + support) where the settings will ultimitely be stored. However, at the + time of this writing the settings will be stored (either on a global or + user basis, preferring locally) into a plist file in + $ROOT/System/Library/Preferences (in XML format). QSettings will create + an appropriate plist file (com.<first group name>.plist) out of the + full path to a key. + + For further information on CFPreferences see also + \link http://developer.apple.com/techpubs/macosx/CoreFoundation/PreferenceServices/preferenceservices_carbon.html + Apple's Specifications\endlink \section1 Notes for Unix Applications There is no universally accepted place for storing application settings under Unix. In the examples the settings file will be searched for in the following directories: @@ -297,26 +326,26 @@ static HANDLE openlock( const QString &name, int /*type*/ ) QT_WA( { fd = CreateFileW( (TCHAR*)name.ucs2(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); } , { fd = CreateFileA( name.local8Bit(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); } ); - if ( !LockFile( fd, 0, 0, -1, -1 ) ) { + if ( !LockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ??? #ifdef QT_CHECK_STATE qWarning( "QSettings: openlock failed!" ); #endif } return fd; } -void closelock( HANDLE fd ) +static void closelock( HANDLE fd ) { if ( !fd ) return; - if ( !UnlockFile( fd, 0, 0, -1, -1 ) ) { + if ( !UnlockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ??? #ifdef QT_CHECK_STATE qWarning( "QSettings: closelock failed!"); #endif } CloseHandle( fd ); } @@ -452,15 +481,17 @@ void QSettingsHeading::parseLine(QTextStream &stream) #endif QSettingsPrivate::QSettingsPrivate( QSettings::Format format ) : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE) { -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( format != QSettings::Ini ) return; +#else + Q_UNUSED( format ); #endif QString appSettings(QDir::homeDirPath() + "/.qt/"); QString defPath; #ifdef Q_WS_WIN #ifdef Q_OS_TEMP @@ -503,12 +534,14 @@ QSettingsPrivate::QSettingsPrivate( QSettings::Format format ) #endif QDir dir(appSettings); if (! dir.exists()) { if (! dir.mkdir(dir.path())) #if defined(QT_CHECK_STATE) qWarning("QSettings: error creating %s", dir.path().latin1()); +#else + ; #endif } if ( !!defPath ) searchPaths.append(defPath); searchPaths.append(dir.path()); @@ -527,12 +560,14 @@ QSettingsGroup QSettingsPrivate::readGroup() if (headingsit != headings.end()) hd = *headingsit; QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); + if ( !globalScope ) + ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { hd.read(fn); hd.insert(fn + "cached", QSettingsGroup()); @@ -561,12 +596,14 @@ void QSettingsPrivate::removeGroup(const QString &key) if (headingsit != headings.end()) hd = *headingsit; QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); + if ( !globalScope ) + ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { hd.read(fn); hd.insert(fn + "cached", QSettingsGroup()); @@ -612,12 +649,14 @@ void QSettingsPrivate::writeGroup(const QString &key, const QString &value) if (headingsit != headings.end()) hd = *headingsit; QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); + if ( !globalScope ) + ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { hd.read(fn); hd.insert(fn + "cached", QSettingsGroup()); @@ -646,32 +685,40 @@ QDateTime QSettingsPrivate::modificationTime() QSettingsHeading hd = headings[heading]; QSettingsGroup grp = hd[group]; QDateTime datetime; QStringList::Iterator it = searchPaths.begin(); + if ( !globalScope ) + ++it; while (it != searchPaths.end()) { QFileInfo fi((*it++) + "/" + heading + "rc"); if (fi.exists() && fi.lastModified() > datetime) datetime = fi.lastModified(); } return datetime; } -static bool verifyKey( const QString &key ) +bool qt_verify_key( const QString &key ) { if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\\\r\\\\n" ) ) ) return FALSE; return TRUE; } static inline QString groupKey( const QString &group, const QString &key ) { - if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) + if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) { + // group is empty, or it contains a single '/', so we just return the key + if ( key.startsWith( "/" ) ) + return key; + return "/" + key; + } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) { return group + key; + } return group + "/" + key; } /*! Inserts \a path into the settings search path. The semantics of \a path depends on the system \a s. @@ -683,13 +730,13 @@ static inline QString groupKey( const QString &group, const QString &key ) When \a s is \e Windows, and the execution environment is Windows, the search path list will be used as the first subfolder of the "Software" folder in the registry. When reading settings the folders are searched forwards from the first folder (listed below) to the last, returning the first - settings found, and ignoring any folders for which the user doesn't + settings found, and ignoring any folders for which the user doesn't have read permission. \list 1 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication \i HKEY_CURRENT_USER/Software/MyApplication \i HKEY_LOCAL_MACHINE/Software/MyApplication @@ -707,13 +754,13 @@ static inline QString groupKey( const QString &group, const QString &key ) \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication \i HKEY_LOCAL_MACHINE/Software/MyApplication \i HKEY_CURRENT_USER/Software/MyApplication \endlist If a setting is found in the HKEY_CURRENT_USER space, this setting - is overwritten independently of write permissions in the + is overwritten independently of write permissions in the HKEY_LOCAL_MACHINE space. When \a s is \e Unix, and the execution environment is Unix, the search path list will be used when trying to determine a suitable filename for reading and writing settings files. By default, there are two entries in the search path: @@ -754,40 +801,55 @@ static inline QString groupKey( const QString &group, const QString &key ) \sa removeSearchPath() */ void QSettings::insertSearchPath( System s, const QString &path) { -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) { d->sysInsertSearchPath( s, path ); return; } #endif - if ( !verifyKey( path ) ) { +#if !defined(Q_WS_WIN) + if ( s == Windows ) + return; +#endif +#if !defined(Q_WS_WIN) + if ( s == Mac ) + return; +#endif + + if ( !qt_verify_key( path ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); #endif return; } -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd && s != Unix ) { #else if ( s != Unix ) { #endif -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MAC) if(s != Mac) //mac is respected on the mac as well #endif return; } + QString realPath = path; +#if defined(Q_WS_WIN) + QString defPath = d->globalScope ? d->searchPaths.first() : d->searchPaths.last(); + realPath = defPath + path; +#endif + QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last()); if (it != d->searchPaths.end()) { - d->searchPaths.insert(it, path); + d->searchPaths.insert(it, realPath); } } /*! Removes all occurrences of \a path (using exact matching) from the @@ -795,31 +857,31 @@ void QSettings::insertSearchPath( System s, const QString &path) paths cannot be removed. \sa insertSearchPath() */ void QSettings::removeSearchPath( System s, const QString &path) { - if ( !verifyKey( path ) ) { + if ( !qt_verify_key( path ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); #endif return; } #ifdef Q_WS_WIN if ( d->sysd ) { d->sysRemoveSearchPath( s, path ); return; } #endif -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd && s != Unix ) { #else if ( s != Unix ) { #endif -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MAC) if(s != Mac) //mac is respected on the mac as well #endif return; } if (path == d->searchPaths.first() || path == d->searchPaths.last()) @@ -834,13 +896,13 @@ void QSettings::removeSearchPath( System s, const QString &path) */ QSettings::QSettings() { d = new QSettingsPrivate( Native ); Q_CHECK_PTR(d); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) d->sysd = 0; d->sysInit(); #endif } /*! @@ -851,13 +913,13 @@ QSettings::QSettings() */ QSettings::QSettings( Format format ) { d = new QSettingsPrivate( format ); Q_CHECK_PTR(d); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) d->sysd = 0; if ( format == Native ) d->sysInit(); #else Q_UNUSED(format); #endif @@ -869,13 +931,13 @@ QSettings::QSettings( Format format ) */ QSettings::~QSettings() { sync(); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) d->sysClear(); #endif delete d; } @@ -884,13 +946,13 @@ QSettings::~QSettings() /*! \internal Writes all modifications to the settings to disk. If any errors are encountered, this function returns FALSE, otherwise it will return TRUE. */ bool QSettings::sync() { -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysSync(); #endif if (! d->modified) // fake success return TRUE; @@ -902,27 +964,29 @@ bool QSettings::sync() // determine filename QSettingsHeading hd(*it); QSettingsHeading::Iterator hdit = hd.begin(); QFile file; QStringList::Iterator pit = d->searchPaths.begin(); + if ( !d->globalScope ) + ++pit; while (pit != d->searchPaths.end()) { QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_"); QFileInfo di(*pit); QFileInfo fi((*pit++) + "/" + filebase + "rc"); if ((fi.exists() && fi.isFile() && fi.isWritable()) || (! fi.exists() && di.isDir() && di.isWritable())) { file.setName(fi.filePath()); break; } } - it++; + ++it; - if (file.name().isNull() || file.name().isEmpty()) { + if ( file.name().isEmpty() ) { #ifdef QT_CHECK_STATE qWarning("QSettings::sync: filename is null/empty"); #endif // QT_CHECK_STATE success = FALSE; @@ -960,19 +1024,19 @@ bool QSettings::sync() } else { v.replace("\\", "\\\\"); // escape backslash v.replace("\n", "\\n"); // escape newlines } stream << grpit.key() << "=" << v << endl; - grpit++; + ++grpit; } stream << endl; } - hdit++; + ++hdit; } if (file.status() != IO_Ok) { #ifdef QT_CHECK_STATE qWarning("QSettings::sync: error at end of write"); @@ -1005,29 +1069,28 @@ bool QSettings::sync() /*! \internal */ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif if ( ok ) *ok = FALSE; return def; } - QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadBoolEntry( theKey, def, ok ); + return d->sysReadBoolEntry( groupKey( group(), key ), def, ok ); #endif - QString value = readEntry( theKey, ( def ? "true" : "false" ), ok ); + QString value = readEntry( key, ( def ? "true" : "false" ), ok ); if (value.lower() == "true") return TRUE; else if (value.lower() == "false") return FALSE; else if (value == "1") @@ -1057,29 +1120,28 @@ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) /*! \internal */ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif if ( ok ) *ok = FALSE; return def; } - QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadDoubleEntry( theKey, def, ok ); + return d->sysReadDoubleEntry( groupKey( group(), key ), def, ok ); #endif - QString value = readEntry( theKey, QString::number(def), ok ); + QString value = readEntry( key, QString::number(def), ok ); bool conv_ok; double retval = value.toDouble( &conv_ok ); if ( conv_ok ) return retval; if ( ! value.isEmpty() ) qWarning( "QSettings::readDoubleEntry: '%s' is not a number", @@ -1103,29 +1165,27 @@ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) /*! \internal */ int QSettings::readNumEntry(const QString &key, int def, bool *ok ) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::readNumEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif if ( ok ) *ok = FALSE; return def; } - QString theKey = groupKey( group(), key ); - -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadNumEntry( theKey, def, ok ); + return d->sysReadNumEntry( groupKey( group(), key ), def, ok ); #endif - QString value = readEntry( theKey, QString::number( def ), ok ); + QString value = readEntry( key, QString::number( def ), ok ); bool conv_ok; int retval = value.toInt( &conv_ok ); if ( conv_ok ) return retval; if ( ! value.isEmpty() ) qWarning( "QSettings::readNumEntry: '%s' is not a number", @@ -1149,25 +1209,25 @@ int QSettings::readNumEntry(const QString &key, int def, bool *ok ) /*! \internal */ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::readEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif if ( ok ) *ok = FALSE; return def; } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysReadEntry( theKey, def, ok ); #endif if ( ok ) // no, everything is not ok *ok = FALSE; @@ -1203,17 +1263,19 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) realkey = list.join("/"); } } else realkey = theKey; QSettingsGroup grp = d->readGroup(); - QString retval = grp[realkey]; - if ( retval.isNull() ) - retval = def; - else if ( ok ) // everything is ok - *ok = TRUE; + QSettingsGroup::const_iterator it = grp.find( realkey ), end = grp.end(); + QString retval = def; + if ( it != end ) { + // found the value we needed + retval = *it; + if ( ok ) *ok = TRUE; + } return retval; } #if !defined(Q_NO_BOOL_TYPE) /*! @@ -1225,27 +1287,25 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) returned; otherwise TRUE is returned. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, bool value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } - QString theKey = groupKey( group(), key ); - -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( theKey, value ); + return d->sysWriteEntry( groupKey( group(), key ), value ); #endif QString s(value ? "true" : "false"); - return writeEntry(theKey, s); + return writeEntry(key, s); } #endif /*! \overload @@ -1257,27 +1317,25 @@ bool QSettings::writeEntry(const QString &key, bool value) returned; otherwise TRUE is returned. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, double value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } - QString theKey = groupKey( group(), key ); - -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( theKey, value ); + return d->sysWriteEntry( groupKey( group(), key ), value ); #endif QString s(QString::number(value)); - return writeEntry(theKey, s); + return writeEntry(key, s); } /*! \overload Writes the integer entry \a value into key \a key. The \a key is @@ -1288,27 +1346,25 @@ bool QSettings::writeEntry(const QString &key, double value) returned; otherwise TRUE is returned. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, int value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } - QString theKey = groupKey( group(), key ); - -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( theKey, value ); + return d->sysWriteEntry( groupKey( group(), key ), value ); #endif QString s(QString::number(value)); - return writeEntry(theKey, s); + return writeEntry(key, s); } /*! \internal @@ -1324,22 +1380,20 @@ bool QSettings::writeEntry(const QString &key, int value) unchanged. \sa readEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, const char *value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } - QString theKey = groupKey( group(), key ); - - return writeEntry(theKey, QString(value)); + return writeEntry(key, QString(value)); } /*! \overload Writes the string entry \a value into key \a key. The \a key is @@ -1351,22 +1405,22 @@ bool QSettings::writeEntry(const QString &key, const char *value) returned; otherwise TRUE is returned. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, const QString &value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysWriteEntry( theKey, value ); #endif // NOTE: we *do* allow value to be a null/empty string QString realkey; @@ -1412,22 +1466,22 @@ bool QSettings::writeEntry(const QString &key, const QString &value) Returns TRUE if the entry existed and was removed; otherwise returns FALSE. \sa readEntry(), writeEntry() */ bool QSettings::removeEntry(const QString &key) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::removeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysRemoveEntry( theKey ); #endif QString realkey; @@ -1491,22 +1545,22 @@ bool QSettings::removeEntry(const QString &key) "/MyCompany/MyApplication/geometry/y". \sa subkeyList() */ QStringList QSettings::entryList(const QString &key) const { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::entryList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); #endif return QStringList(); } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysEntryList( theKey ); #endif QString realkey; if (theKey[0] == '/') { @@ -1541,13 +1595,13 @@ QStringList QSettings::entryList(const QString &key) const QSettingsGroup grp = d->readGroup(); QSettingsGroup::Iterator it = grp.begin(); QStringList ret; QString itkey; while (it != grp.end()) { itkey = it.key(); - it++; + ++it; if ( realkey.length() > 0 ) { if ( itkey.left( realkey.length() ) != realkey ) continue; else itkey.remove( 0, realkey.length() + 1 ); @@ -1588,39 +1642,42 @@ QStringList QSettings::entryList(const QString &key) const rather than subkeys use entryList(). \sa entryList() */ QStringList QSettings::subkeyList(const QString &key) const { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::subkeyList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); #endif return QStringList(); } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysSubkeyList( theKey ); #endif QString realkey; + int subkeycount = 2; if (theKey[0] == '/') { // parse our key QStringList list(QStringList::split('/', theKey)); if (list.count() < 1) { #ifdef QT_CHECK_STATE qWarning("QSettings::subkeyList: invalid key '%s'", theKey.latin1()); #endif // QT_CHECK_STATE return QStringList(); } + subkeycount = list.count(); + if (list.count() == 1) { d->heading = list[0]; d->group = "General"; } else { d->heading = list[0]; d->group = list[1]; @@ -1629,22 +1686,34 @@ QStringList QSettings::subkeyList(const QString &key) const list.remove(list.at(1)); // remove the heading from the list list.remove(list.at(0)); realkey = list.join("/"); } + } else realkey = theKey; + QStringList ret; + if ( subkeycount == 1 ) { + QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin(); + while ( it != d->headings.end() ) { + if ( it.key() != "General" && ! ret.contains( it.key() ) ) + ret << it.key(); + ++it; + } + + return ret; + } + QSettingsGroup grp = d->readGroup(); QSettingsGroup::Iterator it = grp.begin(); - QStringList ret; QString itkey; while (it != grp.end()) { itkey = it.key(); - it++; + ++it; if ( realkey.length() > 0 ) { if ( itkey.left( realkey.length() ) != realkey ) continue; else itkey.remove( 0, realkey.length() + 1 ); @@ -1667,22 +1736,22 @@ QStringList QSettings::subkeyList(const QString &key) const \internal This function returns the time of last modification for \a key. */ QDateTime QSettings::lastModficationTime(const QString &key) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::lastModficationTime: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return QDateTime(); } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return QDateTime(); #endif if (theKey[0] == '/') { // parse our key @@ -1712,15 +1781,23 @@ QDateTime QSettings::lastModficationTime(const QString &key) /*! \overload Writes the string list entry \a value into key \a key. The \a key is created if it doesn't exist. Any previous value is overwritten by \a value. The list is stored as a sequence of strings separated - by \a separator, so none of the strings in the list should contain - the separator. If the list is empty or null the key's value will - be an empty string. + by \a separator (using QStringList::join()), so none of the + strings in the list should contain the separator. If the list is + empty or null the key's value will be an empty string. + + \warning The list should not contain empty or null strings, as + readListEntry() will use QStringList::split() to recreate the + list. As the documentation states, QStringList::split() will omit + empty strings from the list. Because of this, it is impossible to + retrieve identical list data that is stored with this function. + We recommend using the writeEntry() and readListEntry() overloads + that do not take a \a separator argument. If an error occurs the settings are left unchanged and FALSE is returned; otherwise returns TRUE. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ @@ -1765,12 +1842,19 @@ bool QSettings::writeEntry(const QString &key, const QStringList &value) Reads the entry specified by \a key as a string. The \a separator is used to create a QStringList by calling QStringList::split(\a separator, entry). If \a ok is not 0: \a *ok is set to TRUE if the key was read, otherwise \a *ok is set to FALSE. + \warning As the documentation states, QStringList::split() will + omit empty strings from the list. Because of this, it is + impossible to retrieve identical list data with this function. We + recommend using the readListEntry() and writeEntry() overloads + that do not take a \a separator argument. + + Note that if you want to iterate over the list, you should iterate over a copy, e.g. \code QStringList list = mySettings.readListEntry( "size", " " ); QStringList::Iterator it = list.begin(); while( it != list.end() ) { @@ -1844,25 +1928,32 @@ QStringList QSettings::readListEntry(const QString &key, bool *ok ) l.append(s); } } return l; } +#ifdef Q_OS_MAC +void qt_setSettingsBasePath(const QString &); //qsettings_mac.cpp +#endif + /*! - Insert platform-dependent paths from platform-independent information. + Insert platform-dependent paths from platform-independent information. + + The \a domain should be an Internet domain name + controlled by the producer of the software, eg. Trolltech products + use "trolltech.com". - The \a domain should be an Internet domain name - controlled by the producer of the software, eg. Trolltech products - use "trolltech.com". + The \a product should be the official name of the product. - The \a product should be the official name of the product. + The \a scope should be + QSettings::User for user-specific settings, or + QSettings::Global for system-wide settings (generally + these will be read-only to many users). - The \a scope should be - QSettings::User for user-specific settings, or - QSettings::Global for system-wide settings (generally - these will be read-only to many users). + Not all information is relevant on all systems (e.g. scoping is + currently used only if QSettings accesses the Windows registry). */ void QSettings::setPath( const QString &domain, const QString &product, Scope scope ) { // On Windows, any trailing ".com(\..*)" is stripped from the domain. The // Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to @@ -1870,51 +1961,65 @@ void QSettings::setPath( const QString &domain, const QString &product, Scope sc // write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped // from the domain. The Global scope corresponds to "/opt" (this would be // configurable at library build time - eg. to "/usr/local" or "/usr"), // while the User scope corresponds to $HOME/.*rc. // Note that on most installations, not all users can write to the System // scope. -// +// // On MacOS X, if there is no "." in domain, append ".com", then reverse the // order of the elements (Mac OS uses "com.apple.finder" as domain+product). // The Global scope corresponds to /Library/Preferences/*.plist, while the // User scope corresponds to ~/Library/Preferences/*.plist. // Note that on most installations, not all users can write to the System // scope. + d->globalScope = scope == Global; + QString actualSearchPath; int lastDot = domain.findRev( '.' ); #if defined(Q_WS_WIN) actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; insertSearchPath( Windows, actualSearchPath ); -#elif defined(Q_WS_MAC) +#elif !defined(QWS) && defined(Q_OS_MAC) QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + "."; - if ( topLevelDomain.isEmpty() ) - topLevelDomain = "com."; - actualSearchPath = "/" + topLevelDomain + domain.left( lastDot ) + product; + if ( !topLevelDomain.isEmpty() ) + qt_setSettingsBasePath( topLevelDomain ); + actualSearchPath = "/" + domain.left( lastDot ) + product; insertSearchPath( Mac, actualSearchPath ); #else actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; insertSearchPath( Unix, actualSearchPath ); #endif - - d->globalScope = scope == Global; } /*! Appends \a group to the current key prefix. + + \code + QSettings settings; + settings.beginGroup( "/MainWindow" ); + // read values + settings.endGroup(); + \endcode */ void QSettings::beginGroup( const QString &group ) { d->groupStack.push( group ); d->groupDirty = TRUE; } /*! Undo previous calls to beginGroup(). Note that a single beginGroup("a/b/c") is undone by a single call to endGroup(). + + \code + QSettings settings; + settings.beginGroup( "/MainWindow/Geometry" ); + // read values + settings.endGroup(); + \endcode */ void QSettings::endGroup() { d->groupStack.pop(); d->groupDirty = TRUE; } @@ -1942,13 +2047,13 @@ QString QSettings::group() const QValueStack<QString>::Iterator it = d->groupStack.begin(); while ( it != d->groupStack.end() ) { QString group = *it; ++it; if ( group[0] != '/' ) - group = "/" + group; + group.prepend( "/" ); d->groupPrefix += group; } } return d->groupPrefix; } diff --git a/qmake/tools/qstring.cpp b/qmake/tools/qstring.cpp index 56df62b..7f1fac3 100644 --- a/qmake/tools/qstring.cpp +++ b/qmake/tools/qstring.cpp @@ -2,13 +2,13 @@ ** $Id$ ** ** Implementation of the QString class and related Unicode functions ** ** Created : 920722 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. @@ -44,24 +44,28 @@ #include "qstring.h" #include "qregexp.h" #include "qdatastream.h" #ifndef QT_NO_TEXTCODEC #include "qtextcodec.h" #endif -#include <ctype.h> #include <limits.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #if defined(Q_WS_WIN) #include "qt_windows.h" #endif #if !defined( QT_NO_COMPONENT ) && !defined( QT_LITE_COMPONENT ) #include "qcleanuphandler.h" #endif +#ifdef QT_NO_UNICODETABLES +# include <ctype.h> +#endif + /* ------------------------------------------------------------------------- * unicode information * these tables are generated from the unicode reference file * ftp://ftp.unicode.org/Public/3.2-Update/UnicodeData.txt * @@ -11784,24 +11788,26 @@ static inline QChar::Direction direction( const QChar &c ) { #ifndef QT_NO_UNICODETABLES const Q_UINT8 *rowp = direction_info[c.row()]; if(!rowp) return QChar::DirL; return (QChar::Direction) ( *(rowp+c.cell()) & 0x1f ); #else + Q_UNUSED(c); return QChar::DirL; #endif } static inline bool mirrored( const QChar &c ) { #ifndef QT_NO_UNICODETABLES const Q_UINT8 *rowp = direction_info[c.row()]; if ( !rowp ) return FALSE; return *(rowp+c.cell())>128; #else + Q_UNUSED(c); return FALSE; #endif } #ifndef QT_NO_UNICODETABLES static const Q_UINT16 symmetricPairs[] = { @@ -11897,13 +11903,13 @@ static int ucstrnicmp( const QChar *a, const QChar *b, int l ) static uint computeNewMax( uint len ) { uint newMax = 4; while ( newMax < len ) newMax *= 2; - // try to spare some memory + // try to save some memory if ( newMax >= 1024 * 1024 && len <= newMax - (newMax >> 2) ) newMax -= newMax >> 2; return newMax; } /*! @@ -12888,13 +12894,13 @@ void QString::compose() returning the result. The caller is responsible for deleting the return value with delete[]. */ -QChar* QString::asciiToUnicode( const QByteArray& ba, uint* len ) +QChar* QString::latin1ToUnicode( const QByteArray& ba, uint* len ) { if ( ba.isNull() ) { *len = 0; return 0; } int l = 0; @@ -12907,13 +12913,13 @@ QChar* QString::asciiToUnicode( const QByteArray& ba, uint* len ) *len = l; while (l--) *uc++ = *str++; return result; } -static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len ) +static QChar* internalLatin1ToUnicode( const QByteArray& ba, uint* len ) { if ( ba.isNull() ) { *len = 0; return 0; } int l = 0; @@ -12937,47 +12943,47 @@ static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len ) length of the Unicode string. The caller is responsible for deleting the return value with delete[]. */ -QChar* QString::asciiToUnicode( const char *str, uint* len, uint maxlen ) +QChar* QString::latin1ToUnicode( const char *str, uint* len, uint maxlen ) { QChar* result = 0; uint l = 0; if ( str ) { if ( maxlen != (uint)-1 ) { while ( l < maxlen && str[l] ) l++; } else { // Faster? - l = qstrlen(str); + l = strlen( str ); } QChar *uc = new QChar[ l ]; // Can't use macro since function is public result = uc; uint i = l; while ( i-- ) *uc++ = *str++; } if ( len ) *len = l; return result; } -static QChar* internalAsciiToUnicode( const char *str, uint* len, +static QChar* internalLatin1ToUnicode( const char *str, uint* len, uint maxlen = (uint)-1 ) { QChar* result = 0; uint l = 0; if ( str ) { if ( maxlen != (uint)-1 ) { while ( l < maxlen && str[l] ) l++; } else { // Faster? - l = qstrlen(str); + l = strlen( str ); } QChar *uc = QT_ALLOC_QCHAR_VEC( l ); result = uc; uint i = l; while ( i-- ) *uc++ = *str++; @@ -12991,13 +12997,13 @@ static QChar* internalAsciiToUnicode( const char *str, uint* len, This utility function converts \a l 16-bit characters from \a uc to ASCII, returning a '\0'-terminated string. The caller is responsible for deleting the resultant string with delete[]. */ -char* QString::unicodeToAscii(const QChar *uc, uint l) +char* QString::unicodeToLatin1(const QChar *uc, uint l) { if (!uc) { return 0; } char *a = new char[l+1]; char *result = a; @@ -13154,41 +13160,12 @@ QStringData* QString::makeSharedNull() QString *that = const_cast<QString *>(&QString::null); that->d = QString::shared_null; #endif return QString::shared_null; } -// Uncomment this to get some useful statistics. -// #define Q2HELPER(x) x - -#ifdef Q2HELPER -static int stat_construct_charstar=0; -static int stat_construct_charstar_size=0; -static int stat_construct_null=0; -static int stat_construct_int=0; -static int stat_construct_int_size=0; -static int stat_construct_ba=0; -static int stat_get_ascii=0; -static int stat_get_ascii_size=0; -static int stat_copy_on_write=0; -static int stat_copy_on_write_size=0; -static int stat_fast_copy=0; -Q_EXPORT void qt_qstring_stats() -{ - qDebug("construct_charstar = %d (%d chars)", stat_construct_charstar, stat_construct_charstar_size); - qDebug("construct_null = %d", stat_construct_null); - qDebug("construct_int = %d (%d chars)", stat_construct_int, stat_construct_int_size); - qDebug("construct_ba = %d", stat_construct_ba); - qDebug("get_ascii = %d (%d chars)", stat_get_ascii, stat_get_ascii_size); - qDebug("copy_on_write = %d (%d chars)", stat_copy_on_write, stat_copy_on_write_size); - qDebug("fast_copy = %d", stat_fast_copy); -} -#else -#define Q2HELPER(x) -#endif - /*! \fn QString::QString() Constructs a null string, i.e. both the length and data pointer are 0. @@ -13208,13 +13185,12 @@ QString::QString( QChar ch ) Constructs an implicitly shared copy of \a s. This is very fast since it only involves incrementing a reference count. */ QString::QString( const QString &s ) : d(s.d) { - Q2HELPER(stat_fast_copy++) d->ref(); } /*! \internal @@ -13227,34 +13203,37 @@ QString::QString( const QString &s ) : \sa isNull() */ QString::QString( int size, bool /*dummy*/ ) { if ( size ) { - Q2HELPER(stat_construct_int++) int l = size; - Q2HELPER(stat_construct_int_size+=l) QChar* uc = QT_ALLOC_QCHAR_VEC( l ); d = new QStringData( uc, 0, l ); } else { - Q2HELPER(stat_construct_null++) d = shared_null ? shared_null : (shared_null=new QStringData); d->ref(); } } /*! Constructs a string that is a deep copy of \a ba interpreted as a classic C string. */ QString::QString( const QByteArray& ba ) { - Q2HELPER(stat_construct_ba++) +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + d = 0; + *this = fromAscii( ba.data(), ba.size() ); + return; + } +#endif uint l; - QChar *uc = internalAsciiToUnicode(ba,&l); + QChar *uc = internalLatin1ToUnicode(ba,&l); d = new QStringData(uc,l,l); } /*! Constructs a string that is a deep copy of the first \a length characters in the QChar array. @@ -13299,18 +13278,45 @@ QString::QString( const QChar* unicode, uint length ) \sa isNull() */ QString::QString( const char *str ) { - Q2HELPER(stat_construct_charstar++) +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + d = 0; + *this = fromAscii( str ); + return; + } +#endif + uint l; + QChar *uc = internalLatin1ToUnicode(str,&l); + d = new QStringData(uc,l,l); +} + +#ifndef QT_NO_STL +/*! + Constructs a string that is a deep copy of \a str. + + This is the same as fromAscii(\a str). +*/ + +QString::QString( const std::string &str ) +{ +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + d = 0; + *this = fromAscii( str.c_str() ); + return; + } +#endif uint l; - QChar *uc = internalAsciiToUnicode(str,&l); - Q2HELPER(stat_construct_charstar_size+=l) + QChar *uc = internalLatin1ToUnicode(str.c_str(),&l); d = new QStringData(uc,l,l); } +#endif /*! \fn QString::~QString() Destroys the string and frees the string's data if this is the last reference to the string. @@ -13330,16 +13336,16 @@ void QString::real_detach() { setLength( length() ); } void QString::deref() { - if ( d->deref() ) { + if ( d && d->deref() ) { if ( d != shared_null ) delete d; - d = 0; // helps debugging + d = 0; } } void QStringData::deleteSelf() { delete this; @@ -13349,12 +13355,21 @@ void QStringData::deleteSelf() \fn QString& QString::operator=( QChar c ) Sets the string to contain just the single character \a c. */ /*! + \fn QString& QString::operator=( const std::string& s ) + + \overload + + Makes a deep copy of \a s and returns a reference to the deep + copy. +*/ + +/*! \fn QString& QString::operator=( char c ) \overload Sets the string to contain just the single character \a c. */ @@ -13365,13 +13380,12 @@ void QStringData::deleteSelf() Assigns a shallow copy of \a s to this string and returns a reference to this string. This is very fast because the string isn't actually copied. */ QString &QString::operator=( const QString &s ) { - Q2HELPER(stat_fast_copy++) s.d->ref(); deref(); d = s.d; return *this; } @@ -13380,13 +13394,13 @@ QString &QString::operator=( const QString &s ) Assigns a deep copy of \a cs, interpreted as a classic C string, to this string and returns a reference to this string. */ QString &QString::operator=( const QCString& cs ) { - return setLatin1(cs); + return setAscii(cs); } /*! \overload @@ -13396,13 +13410,13 @@ QString &QString::operator=( const QCString& cs ) If \a str is 0, then a null string is created. \sa isNull() */ QString &QString::operator=( const char *str ) { - return setLatin1(str); + return setAscii(str); } /*! \fn bool QString::isNull() const @@ -13468,14 +13482,13 @@ void QString::truncate( uint newLen ) /*! Ensures that at least \a newLen characters are allocated to the string, and sets the length of the string to \a newLen. Any new space allocated contains arbitrary data. - If \a newLen is 0, then the string becomes empty, unless the - string is null, in which case it remains null. + If \a newLen is 0, then the string becomes empty (non-null). If it is not possible to allocate enough memory, the string remains unchanged. This function always detaches the string from other references to the same data. @@ -13483,18 +13496,18 @@ void QString::truncate( uint newLen ) This function is useful for code that needs to build up a long string and wants to avoid repeated reallocation. In this example, we want to add to the string until some condition is true, and we're fairly sure that size is big enough: \code QString result; - int resultLength = 0; - result.setLength( newLen ) // allocate some space + int len = 0; + result.setLength( maxLen ); // allocate some space while ( ... ) { - result[resultLength++] = ... // fill (part of) the space with data + result[len++] = ... // fill part of the space } - result.truncate[resultLength]; // and get rid of the undefined junk + result.truncate( len ); // and get rid of the rest \endcode If \a newLen is an underestimate, the worst that will happen is that the loop will slow down. \sa truncate(), isNull(), isEmpty(), length() @@ -13502,14 +13515,12 @@ void QString::truncate( uint newLen ) void QString::setLength( uint newLen ) { if ( d->count != 1 || newLen > d->maxl || ( newLen * 4 < d->maxl && d->maxl > 4 ) ) { // detach, grow or shrink - Q2HELPER(stat_copy_on_write++) - Q2HELPER(stat_copy_on_write_size+=d->len) uint newMax = computeNewMax( newLen ); QChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); if ( nd ) { uint len = QMIN( d->len, newLen ); if ( d->unicode ) memcpy( nd, d->unicode, sizeof(QChar)*len ); @@ -13527,27 +13538,26 @@ void QString::setLength( uint newLen ) numbered occurrence of \c %1, \c %2, ..., \c %9 with \a a. The \a fieldwidth value specifies the minimum amount of space that \a a is padded to. A positive value will produce right-aligned text, whereas a negative value will produce left-aligned text. + The following example shows how we could create a 'status' string + when processing a list of files: \code - QString firstName( "Joe" ); - QString lastName( "Bloggs" ); - QString fullName; - fullName = QString( "First name is '%1', last name is '%2'" ) - .arg( firstName ) - .arg( lastName ); - - // fullName == First name is 'Joe', last name is 'Bloggs' + QString status = QString( "Processing file %1 of %2: %3" ) + .arg( i ) // current file's number + .arg( total ) // number of files to process + .arg( fileName ); // current file's name \endcode - Note that using arg() to construct sentences as we've done in the - example above does not usually translate well into other languages - because sentence structure and word order often differ between - languages. + It is generally fine to use filenames and numbers as we have done + in the example above. But note that using arg() to construct + natural language sentences does not usually translate well into + other languages because sentence structure and word order often + differ between languages. If there is no place marker (\c %1 or \c %2, etc.), a warning message (qWarning()) is output and the text is appended at the end of the string. We recommend that the correct number of place markers is always used in production code. */ @@ -13771,13 +13781,13 @@ QString &QString::sprintf( const char* cformat, ... ) if ( !cformat || !*cformat ) { // Qt 1.x compat *this = fromLatin1( "" ); return *this; } - QString format = fromLatin1( cformat ); + QString format = fromAscii( cformat ); QRegExp escape( "%#?0?-? ?\\+?'?[0-9*]*\\.?[0-9*]*h?l?L?q?Z?" ); QString result; uint last = 0; int pos; int len = 0; @@ -13910,13 +13920,13 @@ QString &QString::sprintf( const char* cformat, ... ) break; case 2: ::sprintf( out, in, width, decimals, value ); } } } - replacement = fromLatin1( out ); + replacement = fromAscii( out ); } result += replacement; } *this = result; va_end( ap ); @@ -14121,14 +14131,16 @@ int QString::find( const QString& str, int index, bool cs ) const index += l; if ( sl + index > l ) return -1; if ( !sl ) return index; +#ifndef MACOSX_101 if ( sl == 1 ) return find( *str.unicode(), index, cs ); +#endif // we use the Boyer-Moore algorithm in cases where the overhead // for the hash table should pay off, otherwise we use a simple // hash function if ( l > 500 && sl > 5 ) { uint skiptable[0x100]; @@ -14218,12 +14230,15 @@ int QString::find( const QString& str, int index, bool cs ) const int i = string.findRev( 'a' ); // i == 5 \endcode */ int QString::findRev( QChar c, int index, bool cs ) const { +#ifdef MACOSX_101 + return findRev( QString( c ), index, cs ); +#else const uint l = length(); if ( index < 0 ) index += l; if ( (uint)index >= l ) return -1; const QChar *end = unicode(); @@ -14234,12 +14249,13 @@ int QString::findRev( QChar c, int index, bool cs ) const } else { c = ::lower( c ); while ( uc >= end && ::lower( *uc ) != c ) uc--; } return uc - end; +#endif } /*! \overload Finds the first occurrence of the string \a str, starting at @@ -14270,14 +14286,16 @@ int QString::findRev( const QString& str, int index, bool cs ) const int delta = l-sl; if ( index < 0 || index > (int)l || delta < 0 ) return -1; if ( index > delta ) index = delta; +#ifndef MACOSX_101 if ( sl == 1 ) return findRev( *str.unicode(), index, cs ); +#endif const QChar* needle = str.unicode(); const QChar* haystack = unicode() + index; const QChar* end = unicode(); const uint sl_minus_1 = sl-1; const QChar* n = needle+sl_minus_1; @@ -14976,25 +14994,30 @@ QString QString::rightJustify( uint width, QChar fill, bool truncate ) const \sa upper() */ QString QString::lower() const { - QString s(*this); - int l=length(); - if ( l ) { - s.real_detach(); // could do this only when we find a change - register QChar *p=s.d->unicode; - if ( p ) { - while ( l-- ) { + int l = length(); + register QChar *p = d->unicode; + while ( l ) { + if ( *p != ::lower(*p) ) { + QString s( *this ); + s.real_detach(); + p = s.d->unicode + ( p - d->unicode ); + while ( l ) { *p = ::lower( *p ); + l--; p++; } + return s; } + l--; + p++; } - return s; + return *this; } /*! Returns an uppercase copy of the string. \code @@ -15004,25 +15027,30 @@ QString QString::lower() const \sa lower() */ QString QString::upper() const { - QString s(*this); - int l=length(); - if ( l ) { - s.real_detach(); // could do this only when we find a change - register QChar *p=s.d->unicode; - if ( p ) { - while ( l-- ) { + int l = length(); + register QChar *p = d->unicode; + while ( l ) { + if ( *p != ::upper(*p) ) { + QString s( *this ); + s.real_detach(); + p = s.d->unicode + ( p - d->unicode ); + while ( l ) { *p = ::upper( *p ); + l--; p++; } + return s; } + l--; + p++; } - return s; + return *this; } /*! Returns a string that has whitespace removed from the start and the end. @@ -15134,14 +15162,14 @@ QString &QString::insert( uint index, const QString &s ) return insert( index, s.unicode(), s.length() ); } /*! \overload - Inserts the character in \a s into the string at position \a index - \a len number of times and returns a reference to the string. + Inserts the first \a len characters in \a s into the string at + position \a index and returns a reference to the string. */ QString &QString::insert( uint index, const QChar* s, uint len ) { if ( len == 0 ) return *this; @@ -15248,12 +15276,22 @@ QString &QString::insert( uint index, QChar c ) // insert char Equivalent to insert(0, \a s). \sa insert() */ +/*! \fn QString& QString::prepend( const std::string &s ) + \overload + + Inserts \a s at the beginning of the string and returns a reference to the string. + + Equivalent to insert(0, \a s). + + \sa insert() + */ + /*! \overload Inserts \a s at the beginning of the string and returns a reference to the string. Equivalent to insert(0, \a s). @@ -15845,15 +15883,15 @@ static bool ok_in_base( QChar c, int base ) \sa number() */ long QString::toLong( bool *ok, int base ) const { const QChar *p = unicode(); - long val = 0; + ulong val = 0; int l = length(); - const long max_mult = INT_MAX / base; + const ulong max_mult = LONG_MAX / base; bool is_ok = FALSE; int neg = 0; if ( !p ) goto bye; while ( l && p->isSpace() ) // skip leading space l--,p++; @@ -15880,27 +15918,25 @@ long QString::toLong( bool *ok, int base ) const if ( *p >= 'a' && *p <= 'z' ) dv = *p - 'a' + 10; else dv = *p - 'A' + 10; } if ( val > max_mult || - (val == max_mult && dv > (INT_MAX % base) + neg) ) + (val == max_mult && dv > (LONG_MAX % base) + neg) ) goto bye; val = base * val + dv; p++; } - if ( neg ) - val = -val; while ( l && p->isSpace() ) // skip trailing space - l--,p++; + l--, p++; if ( !l ) is_ok = TRUE; bye: if ( ok ) *ok = is_ok; - return is_ok ? val : 0; + return is_ok ? ( neg ? -( (long) val ) : (long) val ) : 0L; } /*! Returns the string converted to an \c {unsigned long} value to the base \a base, which is 10 by default and must be between 2 and 36. @@ -15912,13 +15948,13 @@ bye: ulong QString::toULong( bool *ok, int base ) const { const QChar *p = unicode(); ulong val = 0; int l = length(); - const ulong max_mult = UINT_MAX / base; + const ulong max_mult = ULONG_MAX / base; bool is_ok = FALSE; if ( !p ) goto bye; while ( l && p->isSpace() ) // skip leading space l--,p++; if ( !l ) @@ -15937,13 +15973,13 @@ ulong QString::toULong( bool *ok, int base ) const } else { if ( *p >= 'a' && *p <= 'z' ) dv = *p - 'a' + 10; else dv = *p - 'A' + 10; } - if ( val > max_mult || (val == max_mult && dv > UINT_MAX % base) ) + if ( val > max_mult || (val == max_mult && dv > ULONG_MAX % base) ) goto bye; val = base * val + dv; p++; } while ( l && p->isSpace() ) // skip trailing space @@ -15964,13 +16000,13 @@ bye: FALSE; otherwise \a *ok is set to TRUE. */ short QString::toShort( bool *ok, int base ) const { long v = toLong( ok, base ); - if ( ok && *ok && (v < -32768 || v > 32767) ) { + if ( ok && *ok && (v < SHRT_MIN || v > SHRT_MAX) ) { *ok = FALSE; v = 0; } return (short)v; } @@ -15983,13 +16019,13 @@ short QString::toShort( bool *ok, int base ) const FALSE; otherwise \a *ok is set to TRUE. */ ushort QString::toUShort( bool *ok, int base ) const { ulong v = toULong( ok, base ); - if ( ok && *ok && (v > 65535) ) { + if ( ok && *ok && (v > USHRT_MAX) ) { *ok = FALSE; v = 0; } return (ushort)v; } @@ -16010,13 +16046,18 @@ ushort QString::toUShort( bool *ok, int base ) const \sa number() */ int QString::toInt( bool *ok, int base ) const { - return (int)toLong( ok, base ); + long v = toLong( ok, base ); + if ( ok && *ok && (v < INT_MIN || v > INT_MAX) ) { + *ok = FALSE; + v = 0; + } + return (int)v; } /*! Returns the string converted to an \c{unsigned int} value to the base \a base, which is 10 by default and must be between 2 and 36. @@ -16025,13 +16066,18 @@ int QString::toInt( bool *ok, int base ) const \sa number() */ uint QString::toUInt( bool *ok, int base ) const { - return (uint)toULong( ok, base ); + ulong v = toULong( ok, base ); + if ( ok && *ok && (v > UINT_MAX) ) { + *ok = FALSE; + v = 0; + } + return (uint)v; } /*! Returns the string converted to a \c double value. If \a ok is not 0: if a conversion error occurs, \a *ok is set to @@ -16049,13 +16095,13 @@ double QString::toDouble( bool *ok ) const { char *end; const char *a = latin1(); double val = strtod( a ? a : "", &end ); if ( ok ) - *ok = ( a && *a && (end == 0 || (end - a) == (int)length()) ); + *ok = ( a && *a && (end == 0 || *end == '\0') ); return val; } /*! Returns the string converted to a \c float value. @@ -16095,17 +16141,17 @@ QString &QString::setNum( long n, int base ) QChar *buf = (QChar*)charbuf; QChar *p = &buf[64]; int len = 0; bool neg; if ( n < 0 ) { neg = TRUE; - if ( n == INT_MIN ) { + if ( n == LONG_MIN ) { // Cannot always negate this special case QString s1, s2; - s1.setNum(n/base); - s2.setNum((-(n+base))%base); + s1.setNum(n/base, base ); + s2.setNum((-(n+base))%base, base ); *this = s1 + s2; return *this; } n = -n; } else { neg = FALSE; @@ -16458,12 +16504,21 @@ void QString::setExpand( uint index, QChar c ) Appends \a str to the string and returns a reference to the result. Equivalent to operator+=(). */ +/*! \fn QString& QString::append( const std::string &str ) + \overload + + Appends \a str to the string and returns a reference to the result. + + Equivalent to operator+=(). + */ + + /*! \fn QString& QString::append( const char *str ) \overload Appends \a str to the string and returns a reference to the result. Equivalent to operator+=(). @@ -16487,15 +16542,21 @@ QString& QString::operator+=( const QString &str ) /*! \overload Appends \a str to the string and returns a reference to the string. */ +#ifndef QT_NO_CAST_ASCII QString& QString::operator+=( const char *str ) { if ( str ) { +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) + return operator+=( fromAscii( str ) ); +#endif + uint len1 = length(); uint len2 = strlen( str ); if ( len2 ) { setLength(len1+len2); uint i = 0; while( i < len2 ) { @@ -16505,12 +16566,13 @@ QString& QString::operator+=( const char *str ) } else if ( isNull() ) { // ## just for 1.x compat: *this = fromLatin1( "" ); } } return *this; } +#endif /*! \overload Appends \a c to the string and returns a reference to the string. */ @@ -16526,71 +16588,100 @@ QString &QString::operator+=( QChar c ) Appends \a c to the string and returns a reference to the string. */ QString &QString::operator+=( char c ) { +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) + return operator+=( fromAscii( &c, 1 ) ); +#endif setLength(length()+1); d->unicode[length()-1] = c; return *this; } /*! \fn QString &QString::operator+=( const QByteArray &str ) \overload Appends \a str to the string and returns a reference to the string. */ +/*! + \fn QString &QString::operator+=( const std::string &str ) + \overload + + Appends \a str to the string and returns a reference to the string. +*/ + /*! \fn char QChar::latin1() const - Returns a latin-1 copy of this character, if this character is in - the latin-1 character set. If not, this function returns 0. + Returns the Latin-1 value of this character, or 0 if it + cannot be represented in Latin-1. */ /*! - Returns a Latin-1 representation of the string. Note that the + Returns a Latin-1 representation of the string. The returned value is undefined if the string contains non-Latin-1 characters. If you want to convert strings into formats other than Unicode, see the QTextCodec classes. This function is mainly useful for boot-strapping legacy code to use Unicode. The result remains valid so long as one unmodified copy of the source string exists. - \sa utf8(), local8Bit() + \sa fromLatin1(), ascii(), utf8(), local8Bit() */ const char* QString::latin1() const { - if ( !d->ascii ) { - Q2HELPER(stat_get_ascii++) - Q2HELPER(stat_get_ascii_size+=d->len) - d->ascii = unicodeToAscii( d->unicode, d->len ); + if ( !d->ascii || !d->islatin1 ) { + d->ascii = unicodeToLatin1( d->unicode, d->len ); + d->islatin1 = TRUE; } return d->ascii; } /*! - \fn const char* QString::ascii() const - \obsolete + Returns an 8-bit ASCII representation of the string. - This function simply calls latin1() and returns the result. + If a codec has been set using QTextCodec::codecForCStrings(), + it is used to convert Unicode to 8-bit char. Otherwise, this function + does the same as latin1(). + + \sa fromAscii(), latin1(), utf8(), local8Bit() */ +const char* QString::ascii() const +{ +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + if ( !d->ascii || d->islatin1 ) { + QCString s = QTextCodec::codecForCStrings()->fromUnicode( *this ); + s.detach(); + d->ascii = s.data(); + d->islatin1 = FALSE; + s.resetRawData( s.data(), s.size() ); // we have stolen the data + } + return d->ascii; + } +#endif // QT_NO_TEXTCODEC + return latin1(); +} /*! - Returns the string encoded in UTF8 format. + Returns the string encoded in UTF-8 format. See QTextCodec for more diverse coding/decoding of Unicode strings. - \sa QString::fromUtf8(), local8Bit(), latin1() + \sa fromUtf8(), ascii(), latin1(), local8Bit() */ QCString QString::utf8() const { int l = length(); int rlen = l*3+1; QCString rstr(rlen); @@ -16630,13 +16721,14 @@ QCString QString::utf8() const */ QString QString::fromUtf8( const char* utf8, int len ) { if ( !utf8 ) return QString::null; - if ( len < 0 ) len = qstrlen( utf8 ); + if ( len < 0 ) + len = strlen( utf8 ); QString result; result.setLength( len ); // worst case QChar *qch = (QChar *)result.unicode(); ushort uc = 0; int need = 0; for (int i=0; i<len; i++) { @@ -16671,34 +16763,64 @@ QString QString::fromUtf8( const char* utf8, int len ) result.truncate( qch - result.unicode() ); return result; } /*! Returns the Unicode string decoded from the first \a len - characters of \a chars, ignoring the rest of \a chars. If \a len - is -1 then the length of \a chars is used. If \a len is bigger - than the length of \a chars then it will use the length of \a - chars. + characters of \a ascii, ignoring the rest of \a ascii. If \a len + is -1 then the length of \a ascii is used. If \a len is bigger + than the length of \a ascii then it will use the length of \a + ascii. + + If a codec has been set using QTextCodec::codecForCStrings(), + it is used to convert Unicode to 8-bit char. Otherwise, this function + does the same as fromLatin1(). This is the same as the QString(const char*) constructor, but you can make that constructor invisible if you compile with the define \c QT_NO_CAST_ASCII, in which case you can explicitly create a - QString from Latin-1 text using this function. + QString from 8-bit ASCII text using this function. \code - QString str = QString::fromLatin1( "123456789", 5 ); + QString str = QString::fromAscii( "123456789", 5 ); // str == "12345" \endcode + */ +QString QString::fromAscii( const char* ascii, int len ) +{ +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + if ( !ascii ) + return QString::null; + if ( len < 0 ) + len = strlen( ascii ); + if ( len == 0 || *ascii == '\0' ) + return QString::fromLatin1( "" ); + return QTextCodec::codecForCStrings()->toUnicode( ascii, len ); + } +#endif + return fromLatin1( ascii, len ); +} + + +/*! + Returns the Unicode string decoded from the first \a len + characters of \a chars, ignoring the rest of \a chars. If \a len + is -1 then the length of \a chars is used. If \a len is bigger + than the length of \a chars then it will use the length of \a + chars. + + \sa fromAscii() */ QString QString::fromLatin1( const char* chars, int len ) { uint l; QChar *uc; if ( len < 0 ) len = -1; - uc = internalAsciiToUnicode( chars, &l, len ); + uc = internalLatin1ToUnicode( chars, &l, len ); return QString( new QStringData(uc, l, l), TRUE ); } /*! \fn const QChar* QString::unicode() const @@ -16706,22 +16828,21 @@ QString QString::fromLatin1( const char* chars, int len ) remains valid until the string is modified. */ /*! Returns the string encoded in a locale-specific format. On X11, this is the QTextCodec::codecForLocale(). On Windows, it is a - system-defined encoding. On Mac OS X, this always uses utf8 as the - encoding. + system-defined encoding. On Mac OS X, this always uses UTF-8 as + the encoding. See QTextCodec for more diverse coding/decoding of Unicode strings. - \sa QString::fromLocal8Bit(), latin1(), utf8() + \sa fromLocal8Bit(), ascii(), latin1(), utf8() */ - QCString QString::local8Bit() const { #ifdef QT_NO_TEXTCODEC return latin1(); #else #ifdef Q_WS_X11 @@ -16737,13 +16858,13 @@ QCString QString::local8Bit() const return QCString(latin1()); //I'm evil.. #endif #ifdef Q_WS_WIN return qt_winQString2MB( *this ); #endif #ifdef Q_WS_QWS - return utf8(); // ##### if there is ANY 8 bit format supported? + return utf8(); // ### if there is any 8 bit format supported? #endif #endif } /*! Returns the Unicode string decoded from the first \a len @@ -16768,13 +16889,14 @@ QString QString::fromLocal8Bit( const char* local8Bit, int len ) #else if ( !local8Bit ) return QString::null; #ifdef Q_WS_X11 QTextCodec* codec = QTextCodec::codecForLocale(); - if ( len < 0 ) len = qstrlen(local8Bit); + if ( len < 0 ) + len = strlen( local8Bit ); return codec ? codec->toUnicode( local8Bit, len ) : fromLatin1( local8Bit, len ); #endif #if defined( Q_WS_MAC ) return fromUtf8(local8Bit,len); @@ -16801,12 +16923,18 @@ QString QString::fromLocal8Bit( const char* local8Bit, int len ) strictly Unicode-clean, you can define the macro \c QT_NO_ASCII_CAST when compiling your code to hide this function so that automatic casts are not done. This has the added advantage that you catch the programming error described in operator!(). */ +/*! + \fn QString::operator std::string() const + + Returns ascii(). +*/ + /*! Returns the QString as a zero terminated array of unsigned shorts if the string is not null; otherwise returns zero. The result remains valid so long as one unmodified @@ -16816,14 +16944,12 @@ const unsigned short *QString::ucs2() const { if ( ! d->unicode ) return 0; unsigned int len = d->len; if ( d->maxl < len + 1 ) { // detach, grow or shrink - Q2HELPER(stat_copy_on_write++) - Q2HELPER(stat_copy_on_write_size += len) uint newMax = computeNewMax( len + 1 ); QChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); if ( nd ) { if ( d->unicode ) memcpy( nd, d->unicode, sizeof(QChar)*len ); ((QString *)this)->deref(); @@ -16980,14 +17106,12 @@ QString& QString::setUnicode( const QChar *unicode, uint len ) d = shared_null ? shared_null : makeSharedNull(); d->ref(); } } else if ( d->count != 1 || len > d->maxl || ( len * 4 < d->maxl && d->maxl > 4 ) ) { // detach, grown or shrink - Q2HELPER(stat_copy_on_write++) - Q2HELPER(stat_copy_on_write_size+=d->len) uint newMax = computeNewMax( len ); QChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); if ( unicode ) memcpy( nd, unicode, sizeof(QChar)*len ); deref(); d = new QStringData( nd, len, newMax ); @@ -17015,12 +17139,34 @@ QString& QString::setUnicodeCodes( const ushort* unicode_as_ushorts, uint len ) { return setUnicode((const QChar*)unicode_as_ushorts, len); } /*! + Sets this string to \a str, interpreted as a classic 8-bit ASCII C + string. If \a len is -1 (the default), then it is set to + strlen(str). + + If \a str is 0 a null string is created. If \a str is "", an empty + string is created. + + \sa isNull(), isEmpty() +*/ + +QString &QString::setAscii( const char *str, int len ) +{ +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + *this = QString::fromAscii( str, len ); + return *this; + } +#endif // QT_NO_TEXTCODEC + return setLatin1( str, len ); +} + +/*! Sets this string to \a str, interpreted as a classic Latin1 C string. If \a len is -1 (the default), then it is set to strlen(str). If \a str is 0 a null string is created. If \a str is "", an empty string is created. @@ -17030,13 +17176,13 @@ QString& QString::setUnicodeCodes( const ushort* unicode_as_ushorts, uint len ) QString &QString::setLatin1( const char *str, int len ) { if ( str == 0 ) return setUnicode(0,0); if ( len < 0 ) - len = qstrlen(str); + len = strlen( str ); if ( len == 0 ) { // won't make a null string *this = QString::fromLatin1( "" ); } else { setUnicode( 0, len ); // resize but not copy QChar *p = d->unicode; while ( len-- ) @@ -17048,22 +17194,22 @@ QString &QString::setLatin1( const char *str, int len ) /*! \internal */ void QString::checkSimpleText() const { QChar *p = d->unicode; QChar *end = p + d->len; - d->simpletext = 1; while( p < end ) { ushort uc = p->unicode(); // sort out regions of complex text formatting if ( uc > 0x058f && ( uc < 0x1100 || uc > 0xfb0f ) ) { - d->simpletext = 0; + d->issimpletext = FALSE; return; } p++; } + d->issimpletext = TRUE; } /*! \fn bool QString::simpleText() const \internal */ diff --git a/qmake/tools/qtextstream.cpp b/qmake/tools/qtextstream.cpp index 75c6531..ddca5bd 100644 --- a/qmake/tools/qtextstream.cpp +++ b/qmake/tools/qtextstream.cpp @@ -1086,13 +1086,13 @@ QTextStream &QTextStream::writeBlock( const QChar* p, uint len ) int l = len; QCString block = d->encoder->fromUnicode( s.string(), l ); dev->writeBlock( block, l ); } else #endif if ( latin1 ) { - char *str = QString::unicodeToAscii( p, len ); + char *str = QString::unicodeToLatin1( p, len ); dev->writeBlock( str, len ); delete [] str; } else if ( internalOrder ) { if ( doUnicodeHeader ) { doUnicodeHeader = FALSE; ts_putc( QChar::byteOrderMark ); diff --git a/qmake/tools/qucom.cpp b/qmake/tools/qucom.cpp index 6086a79..658da97 100644 --- a/qmake/tools/qucom.cpp +++ b/qmake/tools/qucom.cpp @@ -293,46 +293,39 @@ void QUType_int::set( QUObject *o, int v ) o->payload.i = v; o->type = this; } bool QUType_int::canConvertFrom( QUObject *o, QUType *t ) { - if ( isEqual( t, &static_QUType_double ) || - isEqual( t, &static_QUType_float ) ) + if ( isEqual( t, &static_QUType_double ) ) return TRUE; return t->canConvertTo( o, this ); } bool QUType_int::canConvertTo( QUObject * /*o*/, QUType *t ) { - return isEqual( t, &static_QUType_double ) || - isEqual( t, &static_QUType_float ); + return isEqual( t, &static_QUType_double ); } bool QUType_int::convertFrom( QUObject *o, QUType *t ) { if ( isEqual( t, &static_QUType_double ) ) o->payload.i = (long)o->payload.d; - else if ( isEqual( t, &static_QUType_float ) ) - o->payload.i = (long)o->payload.f; else return t->convertTo( o, this ); o->type = this; return TRUE; } bool QUType_int::convertTo( QUObject *o, QUType *t ) { if ( isEqual( t, &static_QUType_double ) ) { o->payload.d = (double)o->payload.i; o->type = &static_QUType_double; - } else if ( isEqual( t, &static_QUType_float ) ) { - o->payload.f = (float)o->payload.i; - o->type = &static_QUType_float; } else return FALSE; return TRUE; } int QUType_int::serializeTo( QUObject *, QUBuffer * ) @@ -342,54 +335,12 @@ int QUType_int::serializeTo( QUObject *, QUBuffer * ) int QUType_int::serializeFrom( QUObject *, QUBuffer * ) { return 0; } -// {5938712A-C496-11D5-8CB2-00C0F03BC0F3} -const QUuid TID_QUType_uint( 0x5938712a, 0xc496, 0x11d5, 0x8c, 0xb2, 0x00, 0xc0, 0xf0, 0x3b, 0xc0, 0xf3); -QUType_uint static_QUType_uint; -const QUuid *QUType_uint::uuid() const { return &TID_QUType_uint; } -const char *QUType_uint::desc() const { return "uint"; } - -void QUType_uint::set( QUObject *o, uint v ) -{ - o->payload.ui = v; - o->type = this; -} - -bool QUType_uint::canConvertFrom( QUObject *o, QUType *t ) -{ - return t->canConvertTo( o, this ); -} - -bool QUType_uint::canConvertTo( QUObject * /*o*/, QUType * /*t*/ ) -{ - return FALSE; -} - -bool QUType_uint::convertFrom( QUObject *o, QUType *t ) -{ - return t->convertTo( o, this ); -} - -bool QUType_uint::convertTo( QUObject * /*o*/, QUType * /*t*/ ) -{ - return FALSE; -} - -int QUType_uint::serializeTo( QUObject *, QUBuffer * ) -{ - return 0; -} - -int QUType_uint::serializeFrom( QUObject *, QUBuffer * ) -{ - return 0; -} - // {2D0974E5-0BA6-4ec2-8837-C198972CB48C} const QUuid TID_QUType_double( 0x2d0974e5, 0xba6, 0x4ec2, 0x88, 0x37, 0xc1, 0x98, 0x97, 0x2c, 0xb4, 0x8c ); QUType_double static_QUType_double; const QUuid *QUType_double::uuid() const { return &TID_QUType_double; } const char *QUType_double::desc() const {return "double"; } @@ -398,32 +349,28 @@ void QUType_double::set( QUObject *o, double v ) o->payload.d = v; o->type = this; } bool QUType_double::canConvertFrom( QUObject *o, QUType *t ) { - if ( isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_float) ) + if ( isEqual( t, &static_QUType_int ) ) return TRUE; return t->canConvertTo( o, this ); } bool QUType_double::canConvertTo( QUObject * /*o*/, QUType *t ) { - return isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_float ); + return isEqual( t, &static_QUType_int ); } bool QUType_double::convertFrom( QUObject *o, QUType *t ) { if ( isEqual( t, &static_QUType_int ) ) o->payload.d = (double)o->payload.i; - else if ( isEqual( t, &static_QUType_float ) ) - o->payload.d = (double)o->payload.f; - else + else return t->convertTo( o, this ); o->type = this; return TRUE; } @@ -447,76 +394,12 @@ int QUType_double::serializeTo( QUObject *, QUBuffer * ) int QUType_double::serializeFrom( QUObject *, QUBuffer * ) { return 0; } - -// {544C5175-6993-4486-B04D-CEC4D21BF4B9 } -const QUuid TID_QUType_float( 0x544c5175, 0x6993, 0x4486, 0xb0, 0x4d, 0xce, 0xc4, 0xd2, 0x1b, 0xf4, 0xb9 ); -QUType_float static_QUType_float; -const QUuid *QUType_float::uuid() const { return &TID_QUType_float; } -const char *QUType_float::desc() const {return "float"; } - -void QUType_float::set( QUObject *o, float v ) -{ - o->payload.f = v; - o->type = this; -} - -bool QUType_float::canConvertFrom( QUObject *o, QUType *t ) -{ - if ( isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_double ) ) - return TRUE; - - return t->canConvertTo( o, this ); -} - -bool QUType_float::canConvertTo( QUObject * /*o*/, QUType *t ) -{ - return isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_double ); -} - -bool QUType_float::convertFrom( QUObject *o, QUType *t ) -{ - if ( isEqual( t, &static_QUType_int ) ) - o->payload.f = (float)o->payload.i; - else if ( isEqual( t, &static_QUType_double ) ) - o->payload.f = (float)o->payload.d; - else - return t->convertTo( o, this ); - - o->type = this; - return TRUE; -} - -bool QUType_float::convertTo( QUObject *o, QUType *t ) -{ - if ( isEqual( t, &static_QUType_int ) ) { - o->payload.i = (int) o->payload.f; - o->type = &static_QUType_int; - } else if ( isEqual( t, &static_QUType_double ) ) { - o->payload.d = (double) o->payload.f; - o->type = &static_QUType_double; - } else - return FALSE; - return TRUE; -} - -int QUType_float::serializeTo( QUObject *, QUBuffer * ) -{ - return 0; -} - -int QUType_float::serializeFrom( QUObject *, QUBuffer * ) -{ - return 0; -} - // {EFCDD1D4-77A3-4b8e-8D46-DC14B8D393E9} const QUuid TID_QUType_charstar( 0xefcdd1d4, 0x77a3, 0x4b8e, 0x8d, 0x46, 0xdc, 0x14, 0xb8, 0xd3, 0x93, 0xe9 ); QUType_charstar static_QUType_charstar; const QUuid *QUType_charstar::uuid() const { return &TID_QUType_charstar; } const char *QUType_charstar::desc() const { return "char*"; } @@ -590,36 +473,32 @@ void QUType_QString::set( QUObject *o, const QString& v ) } bool QUType_QString::canConvertFrom( QUObject *o, QUType *t ) { if ( isEqual( t, &static_QUType_charstar ) || isEqual( t, &static_QUType_double ) || - isEqual( t, &static_QUType_float ) || isEqual( t, &static_QUType_int ) ) return TRUE; return t->canConvertTo( o, this ); } bool QUType_QString::canConvertTo( QUObject * /*o*/, QUType *t ) { return isEqual( t, &static_QUType_charstar ) || isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_double ) || - isEqual( t, &static_QUType_float ); + isEqual( t, &static_QUType_double ); } bool QUType_QString::convertFrom( QUObject *o, QUType *t ) { QString *str = 0; if ( isEqual( t, &static_QUType_charstar ) ) str = new QString( o->payload.charstar.ptr ); else if ( isEqual( t, &static_QUType_double ) ) str = new QString( QString::number( o->payload.d ) ); - else if ( isEqual( t, &static_QUType_float ) ) - str = new QString( QString::number( o->payload.f ) ); else if ( isEqual( t, &static_QUType_int ) ) str = new QString( QString::number( o->payload.i ) ); else return t->convertTo( o, this ); o->type->clear( o ); @@ -638,15 +517,12 @@ bool QUType_QString::convertTo( QUObject *o, QUType *t ) } else if ( isEqual( t, &static_QUType_int ) ) { o->payload.l = str->toLong(); o->type = &static_QUType_int; } else if ( isEqual( t, &static_QUType_double ) ) { o->payload.d = str->toDouble(); o->type = &static_QUType_double; - } else if ( isEqual( t, &static_QUType_float ) ) { - o->payload.d = str->toFloat(); - o->type = &static_QUType_float; } else { return FALSE; } delete str; return TRUE; } diff --git a/qmake/tools/qwaitcondition_unix.cpp b/qmake/tools/qwaitcondition_unix.cpp index 99c1014..6684617 100644 --- a/qmake/tools/qwaitcondition_unix.cpp +++ b/qmake/tools/qwaitcondition_unix.cpp @@ -121,13 +121,13 @@ struct QWaitConditionPrivate { // Key reading thread code for (;;) { getchar(); mymutex.lock(); // Sleep until there are no busy worker threads - while( count > 0 ) { + while( mycount > 0 ) { mymutex.unlock(); sleep( 1 ); mymutex.lock(); } mymutex.unlock(); key_pressed.wakeAll(); @@ -221,33 +221,38 @@ void QWaitCondition::wakeAll() \endlist \sa wakeOne(), wakeAll() */ bool QWaitCondition::wait(unsigned long time) { - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_t mutex; + pthread_mutex_init( &mutex, 0 ); + pthread_mutex_lock( &mutex ); int ret; if (time != ULONG_MAX) { struct timeval tv; gettimeofday(&tv, 0); timespec ti; - ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000; + ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); ti.tv_nsec %= 1000000000; ret = pthread_cond_timedwait(&d->cond, &mutex, &ti); } else ret = pthread_cond_wait(&d->cond, &mutex); #ifdef QT_CHECK_RANGE if (ret && ret != ETIMEDOUT) qWarning("Wait condition wait failure: %s",strerror(ret)); #endif + pthread_mutex_unlock( &mutex ); + pthread_mutex_destroy( &mutex ); + return (ret == 0); } /*! \overload @@ -288,13 +293,13 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time) int ret; if (time != ULONG_MAX) { struct timeval tv; gettimeofday(&tv, 0); timespec ti; - ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000; + ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); ti.tv_nsec %= 1000000000; ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti); } else ret = pthread_cond_wait(&d->cond, &mutex->d->handle); |