00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <QHash>
00012 #include <QFile>
00013 #include <QTextStream>
00014 #include <QTextCodec>
00015 #include <stdlib.h>
00016 #include <stringutil.h>
00017
00018
00019
00020
00021 QString
00022 parse_message_context(const QString &str)
00023 {
00024 QString out = str.trimmed();
00025 out = out.replace("\"", "");
00026 return out;
00027 }
00028
00029
00030
00031 QString
00032 parse_message_context_lame(const QString &str)
00033 {
00034 if (str.contains("#"))
00035 return str.section("#", 0, 0);
00036 return QString();
00037 }
00038
00039
00040
00041
00042 QString
00043 parse_message_string(const QString &msg)
00044 {
00045 QString out = msg.trimmed();
00046
00047 out.replace("\"\n\"", "");
00048 if (out.startsWith("\""))
00049 out = out.remove(0, 1);
00050 if (out.endsWith("\""))
00051 out.chop(1);
00052 out.replace("\\\"", "\"");
00053 out.replace("\\n", "\\r\\n");
00054 out.replace("$\\r\\n", "$\\r$\\n");
00055 return out;
00056 }
00057
00058
00059 QString
00060 read_next_line(QTextStream *stream)
00061 {
00062 stream->skipWhiteSpace();
00063 return stream->readLine().append("\n");
00064 }
00065
00066
00067
00068
00069 void
00070 skip_po_header(QTextStream *po)
00071 {
00072 QString line;
00073
00074 po->skipWhiteSpace();
00075
00076 line = po->readLine();
00077 while (!po->atEnd() && !line.isEmpty())
00078 line = po->readLine();
00079 }
00080
00081
00082
00083
00084
00085 int
00086 po2nsh(QTextStream *po, QString *nsh, const QString &language,
00087 QString *errorMessage)
00088 {
00089 QString line;
00090 QString msgctxt, msgid, msgstr;
00091 QHash<QString,QString> header;
00092 QTextCodec *codec;
00093 int n_strings = 0;
00094
00095 Q_ASSERT(po);
00096 Q_ASSERT(nsh);
00097 Q_ASSERT(errorMessage);
00098
00099 skip_po_header(po);
00100 line = read_next_line(po);
00101 while (!po->atEnd()) {
00102
00103 while (line.startsWith("#")) {
00104 if (line.startsWith("#:")) {
00105
00106 msgctxt = line.section(" ", 1);
00107 msgctxt = parse_message_context_lame(msgctxt);
00108 }
00109 line = read_next_line(po);
00110 }
00111
00112
00113
00114 if (line.startsWith("msgctxt ")) {
00115 msgctxt = line.section(" ", 1);
00116 msgctxt = parse_message_context(msgctxt);
00117 line = read_next_line(po);
00118 }
00119
00120
00121 if (!line.startsWith("msgid ")) {
00122 *errorMessage = "expected 'msgid' line";
00123 return -1;
00124 }
00125 msgid = line.section(" ", 1);
00126
00127 line = read_next_line(po);
00128 while (line.startsWith("\"")) {
00129 msgid.append(line);
00130 line = read_next_line(po);
00131 }
00132 msgid = parse_message_string(msgid);
00133
00134
00135 if (!line.startsWith("msgstr ")) {
00136 *errorMessage = "expected 'msgstr' line";
00137 return -1;
00138 }
00139 msgstr = line.section(" ", 1);
00140
00141 line = read_next_line(po);
00142 while (line.startsWith("\"")) {
00143 msgstr.append(line);
00144 line = read_next_line(po);
00145 }
00146 msgstr = parse_message_string(msgstr);
00147
00148
00149 nsh->append(QString("LangString "));
00150 nsh->append(msgctxt);
00151 nsh->append(QString(" ${LANG_%1} ").arg(language));
00152 if (msgstr.isEmpty())
00153 nsh->append("\"" + msgid + "\"");
00154 else
00155 nsh->append("\"" + msgstr + "\"");
00156 nsh->append("\n");
00157
00158 n_strings++;
00159 }
00160 return n_strings;
00161 }
00162
00163
00164 void
00165 print_usage_and_exit()
00166 {
00167 QTextStream error(stderr);
00168 error << "usage: po2nsh [-q] -i <infile.po> -o <outfile.nsh> "
00169 "-l <language> [-f <from-encoding>] [-t <to-encoding>]\n";
00170 error << " -q (optional) Quiet mode (errors are still displayed)\n";
00171 error << " -i <infile.po> Input .po file\n";
00172 error << " -o <outfile.nsh> Output .nsh file\n";
00173 error << " -l <language> NSIS language table name\n";
00174 error << " -f <from-encoding> .po file encoding (default: utf-8)\n";
00175 error << " -t <to-encoding> .nsh file encoding (default: iso-8859-1)\n";
00176 error.flush();
00177 exit(1);
00178 }
00179
00180 int
00181 main(int argc, char *argv[])
00182 {
00183 QTextStream error(stderr);
00184 QString language, errorMessage;
00185 char *infile, *outfile;
00186 bool quiet = false;
00187 QTextCodec *from_codec = QTextCodec::codecForName("utf-8");
00188 QTextCodec *to_codec = QTextCodec::codecForName("iso-8859-1");
00189
00190
00191 if (argc < 7 || argc > 12)
00192 print_usage_and_exit();
00193 for (int i = 1; i < argc; i++) {
00194 QString arg(argv[i]);
00195 if (!arg.compare("-q", Qt::CaseInsensitive))
00196 quiet = true;
00197 else if (!arg.compare("-i", Qt::CaseInsensitive) && ++i < argc)
00198 infile = argv[i];
00199 else if (!arg.compare("-o", Qt::CaseInsensitive) && ++i < argc)
00200 outfile = argv[i];
00201 else if (!arg.compare("-l", Qt::CaseInsensitive) && ++i < argc)
00202 language = QString(argv[i]).toUpper();
00203 else if (!arg.compare("-f", Qt::CaseInsensitive) && ++i < argc) {
00204 from_codec = QTextCodec::codecForName(argv[i]);
00205 if (!from_codec) {
00206 error << "Invalid input encoding: " << argv[i] << "\n";
00207 return 1;
00208 }
00209 } else if (!arg.compare("-t", Qt::CaseInsensitive) && ++i < argc) {
00210 to_codec = QTextCodec::codecForName(argv[i]);
00211 if (!to_codec) {
00212 error << "Invalid output encoding: " << argv[i] << "\n";
00213 return 1;
00214 }
00215 } else
00216 print_usage_and_exit();
00217 }
00218
00219
00220 QFile poFile(infile);
00221 if (!poFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
00222 error << QString("Unable to open '%1' for reading: %2\n").arg(infile)
00223 .arg(poFile.errorString());
00224 return 2;
00225 }
00226
00227 QString nsh;
00228 QTextStream po(&poFile);
00229 po.setCodec(from_codec);
00230 int n_strings = po2nsh(&po, &nsh, language, &errorMessage);
00231 if (n_strings < 0) {
00232 error << QString("Unable to convert '%1': %2\n").arg(infile)
00233 .arg(errorMessage);
00234 return 3;
00235 }
00236
00237
00238 QFile nshFile(outfile);
00239 if (!nshFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
00240 error << QString("Unable to open '%1' for writing: %2\n").arg(outfile)
00241 .arg(nshFile.errorString());
00242 return 4;
00243 }
00244
00245
00246 QTextStream out(&nshFile);
00247 out.setCodec(to_codec);
00248 out << nsh;
00249
00250 if (!quiet) {
00251 QTextStream results(stdout);
00252 results << QString("Converted %1 strings from %2 to %3.\n").arg(n_strings)
00253 .arg(infile)
00254 .arg(outfile);
00255 }
00256 return 0;
00257 }
00258