src/tools/rcc/main.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the tools applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <rcc.h>
       
    43 #include "../../corelib/kernel/qcorecmdlineargs_p.h"
       
    44 
       
    45 #include <QDebug>
       
    46 #include <QDir>
       
    47 #include <QFile>
       
    48 #include <QFileInfo>
       
    49 #include <QTextStream>
       
    50 
       
    51 QT_BEGIN_NAMESPACE
       
    52 
       
    53 void showHelp(const QString &argv0, const QString &error)
       
    54 {
       
    55     fprintf(stderr, "Qt resource compiler\n");
       
    56     if (!error.isEmpty())
       
    57         fprintf(stderr, "%s: %s\n", qPrintable(argv0), qPrintable(error));
       
    58     fprintf(stderr, "Usage: %s  [options] <inputs>\n\n"
       
    59         "Options:\n"
       
    60         "  -o file              write output to file rather than stdout\n"
       
    61         "  -name name           create an external initialization function with name\n"
       
    62         "  -threshold level     threshold to consider compressing files\n"
       
    63         "  -compress level      compress input files by level\n"
       
    64         "  -root path           prefix resource access path with root path\n"
       
    65         "  -no-compress         disable all compression\n"
       
    66         "  -binary              output a binary file for use as a dynamic resource\n"
       
    67         "  -namespace           turn off namespace macros\n"
       
    68         "  -project             Output a resource file containing all\n"
       
    69         "                       files from the current directory\n"
       
    70         "  -version             display version\n"
       
    71         "  -help                display this information\n",
       
    72         qPrintable(argv0));
       
    73 }
       
    74 
       
    75 void dumpRecursive(const QDir &dir, QTextStream &out)
       
    76 {
       
    77     QFileInfoList entries = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot
       
    78                                               | QDir::NoSymLinks);
       
    79     foreach (QFileInfo entry, entries) {
       
    80         if (entry.isDir()) {
       
    81             dumpRecursive(entry.filePath(), out);
       
    82         } else {
       
    83             out << QLatin1String("<file>")
       
    84                 << entry.filePath()
       
    85                 << QLatin1String("</file>\n");
       
    86         }
       
    87     }
       
    88 }
       
    89 
       
    90 int createProject(const QString &outFileName)
       
    91 {
       
    92     QDir currentDir = QDir::current();
       
    93     QString currentDirName = currentDir.dirName();
       
    94     if (currentDirName.isEmpty())
       
    95         currentDirName = QLatin1String("root");
       
    96 
       
    97     QFile file;
       
    98     bool isOk = false;
       
    99     if (outFileName.isEmpty()) {
       
   100         isOk = file.open(stdout, QFile::WriteOnly | QFile::Text);
       
   101     } else {
       
   102         file.setFileName(outFileName);
       
   103         isOk = file.open(QFile::WriteOnly | QFile::Text);
       
   104     }
       
   105     if (!isOk) {
       
   106         fprintf(stderr, "Unable to open %s: %s\n",
       
   107                 outFileName.isEmpty() ? qPrintable(outFileName) : "standard output",
       
   108                 qPrintable(file.errorString()));
       
   109         return 1;
       
   110     }
       
   111 
       
   112     QTextStream out(&file);
       
   113     out << QLatin1String("<!DOCTYPE RCC><RCC version=\"1.0\">\n"
       
   114                          "<qresource>\n");
       
   115 
       
   116     // use "." as dir to get relative file pathes
       
   117     dumpRecursive(QDir(QLatin1String(".")), out);
       
   118 
       
   119     out << QLatin1String("</qresource>\n"
       
   120                          "</RCC>\n");
       
   121 
       
   122     return 0;
       
   123 }
       
   124 
       
   125 int runRcc(int argc, char *argv[])
       
   126 {
       
   127     QString outFilename;
       
   128     bool helpRequested = false;
       
   129     bool list = false;
       
   130     bool projectRequested = false;
       
   131     QStringList filenamesIn;
       
   132 
       
   133     QStringList args = qCmdLineArgs(argc, argv);
       
   134 
       
   135     RCCResourceLibrary library;
       
   136 
       
   137     //parse options
       
   138     QString errorMsg;
       
   139     for (int i = 1; i < args.count() && errorMsg.isEmpty(); i++) {
       
   140         if (args[i].isEmpty())
       
   141             continue;
       
   142         if (args[i][0] == QLatin1Char('-')) {   // option
       
   143             QString opt = args[i];
       
   144             if (opt == QLatin1String("-o")) {
       
   145                 if (!(i < argc-1)) {
       
   146                     errorMsg = QLatin1String("Missing output name");
       
   147                     break;
       
   148                 }
       
   149                 outFilename = args[++i];
       
   150             } else if (opt == QLatin1String("-name")) {
       
   151                 if (!(i < argc-1)) {
       
   152                     errorMsg = QLatin1String("Missing target name");
       
   153                     break;
       
   154                 }
       
   155                 library.setInitName(args[++i]);
       
   156             } else if (opt == QLatin1String("-root")) {
       
   157                 if (!(i < argc-1)) {
       
   158                     errorMsg = QLatin1String("Missing root path");
       
   159                     break;
       
   160                 }
       
   161                 library.setResourceRoot(QDir::cleanPath(args[++i]));
       
   162                 if (library.resourceRoot().isEmpty()
       
   163                         || library.resourceRoot().at(0) != QLatin1Char('/'))
       
   164                     errorMsg = QLatin1String("Root must start with a /");
       
   165             } else if (opt == QLatin1String("-compress")) {
       
   166                 if (!(i < argc-1)) {
       
   167                     errorMsg = QLatin1String("Missing compression level");
       
   168                     break;
       
   169                 }
       
   170                 library.setCompressLevel(args[++i].toInt());
       
   171             } else if (opt == QLatin1String("-threshold")) {
       
   172                 if (!(i < argc-1)) {
       
   173                     errorMsg = QLatin1String("Missing compression threshold");
       
   174                     break;
       
   175                 }
       
   176                 library.setCompressThreshold(args[++i].toInt());
       
   177             } else if (opt == QLatin1String("-binary")) {
       
   178                 library.setFormat(RCCResourceLibrary::Binary);
       
   179             } else if (opt == QLatin1String("-namespace")) {
       
   180                 library.setUseNameSpace(!library.useNameSpace());
       
   181             } else if (opt == QLatin1String("-verbose")) {
       
   182                 library.setVerbose(true);
       
   183             } else if (opt == QLatin1String("-list")) {
       
   184                 list = true;
       
   185             } else if (opt == QLatin1String("-version") || opt == QLatin1String("-v")) {
       
   186                 fprintf(stderr, "Qt Resource Compiler version %s\n", QT_VERSION_STR);
       
   187                 return 1;
       
   188             } else if (opt == QLatin1String("-help") || opt == QLatin1String("-h")) {
       
   189                 helpRequested = true;
       
   190             } else if (opt == QLatin1String("-no-compress")) {
       
   191                 library.setCompressLevel(-2);
       
   192             } else if (opt == QLatin1String("-project")) {
       
   193                 projectRequested = true;
       
   194             } else {
       
   195                 errorMsg = QString::fromLatin1("Unknown option: '%1'").arg(args[i]);
       
   196             }
       
   197         } else {
       
   198             if (!QFile::exists(args[i])) {
       
   199                 qWarning("%s: File does not exist '%s'",
       
   200                     qPrintable(args[0]), qPrintable(args[i]));
       
   201                 return 1;
       
   202             }
       
   203             filenamesIn.append(args[i]);
       
   204         }
       
   205     }
       
   206 
       
   207     if (projectRequested && !helpRequested) {
       
   208         return createProject(outFilename);
       
   209     }
       
   210 
       
   211     if (!filenamesIn.size() || !errorMsg.isEmpty() || helpRequested) {
       
   212         showHelp(args[0], errorMsg);
       
   213         return 1;
       
   214     }
       
   215     QFile errorDevice;
       
   216     errorDevice.open(stderr, QIODevice::WriteOnly|QIODevice::Text);
       
   217     
       
   218     if (library.verbose())
       
   219         errorDevice.write("Qt resource compiler\n");
       
   220 
       
   221     library.setInputFiles(filenamesIn);
       
   222 
       
   223     if (!library.readFiles(list, errorDevice))
       
   224         return 1;
       
   225 
       
   226     // open output
       
   227     QFile out;
       
   228     QIODevice::OpenMode mode = QIODevice::WriteOnly;
       
   229     if (library.format() == RCCResourceLibrary::C_Code)
       
   230         mode |= QIODevice::Text;
       
   231 
       
   232     if (outFilename.isEmpty() || outFilename == QLatin1String("-")) {
       
   233         // using this overload close() only flushes.
       
   234         out.open(stdout, mode);
       
   235     } else {
       
   236         out.setFileName(outFilename);
       
   237         if (!out.open(mode)) {
       
   238             const QString msg = QString::fromUtf8("Unable to open %1 for writing: %2\n").arg(outFilename).arg(out.errorString());
       
   239             errorDevice.write(msg.toUtf8());
       
   240             return 1;
       
   241         }
       
   242     }
       
   243 
       
   244     // do the task
       
   245     if (list) {
       
   246         const QStringList data = library.dataFiles();
       
   247         for (int i = 0; i < data.size(); ++i) {
       
   248             out.write(qPrintable(QDir::cleanPath(data.at(i))));
       
   249             out.write("\n");
       
   250         }
       
   251         return 0;
       
   252     } 
       
   253 
       
   254     return library.output(out, errorDevice) ? 0 : 1;
       
   255 }
       
   256 
       
   257 QT_END_NAMESPACE
       
   258 
       
   259 int main(int argc, char *argv[])
       
   260 {
       
   261     return QT_PREPEND_NAMESPACE(runRcc)(argc, argv);
       
   262 }