66 #include <QCoreApplication>
69 #include <QXmlFormatter>
70 #include <QTextStream>
71 #include <QTemporaryFile>
72 #include <QDomDocument>
74 #include <QStringList>
80 QString qmake_append =
81 "\n\nALXFILE = @\nOTHER_FILES += @\narcslibrary.output = alm_${QMAKE_FILE_BASE}.cpp\n" \
82 "arcslibrary.input = ALXFILE\narcslibrary.commands = arcslibmaker ${QMAKE_FILE_NAME}\n" \
83 "arcslibrary.variable_out = SOURCES\n" \
84 "QMAKE_EXTRA_COMPILERS += arcslibrary\n";
86 QString qmake_preamble =
87 "INCLUDEPATH += $$(ARCSDIR)/include\n" \
88 "LIBS += -L$$(ARCSDIR)/lib -larcs\n "\
91 QStringList capList(QString pattern,QString input)
94 QRegExp regexp(pattern);
95 regexp.setMinimal(
true);
98 while ((pos = regexp.indexIn(input, pos)) != -1) {
99 res << regexp.cap(1) ;
100 pos += regexp.matchedLength();
106 bool isLibraryFile(QString fileName)
108 QFile file(fileName);
109 if (!file.open(QIODevice::ReadOnly))
111 bool res = QTextStream(&file).readAll().contains(QRegExp(
"\\sMETALIB_BEGIN\\s"));
116 void processHeader(QString fileName)
119 QFile input(fileName);
120 if (!input.open(QIODevice::ReadOnly))
122 std::cerr <<
"Failed to read " << qPrintable(fileName) << std::endl;
125 QString contents = QTextStream(&input).readAll();
128 QRegExp constructFilter(
"[(]\\s*QObject\\s*\\*\\s*(\\w*)\\s*=\\s*0\\s*,\\s*const\\s*char\\s*\\*\\s*(\\w*)\\s*=\\s*0\\s*[)]\\s*:\\s*(\\w*)\\s*[(]\\s*\\1\\s*,\\s*\\2\\s*[)]");
129 constructFilter.setMinimal(
true);
133 while ((pos = constructFilter.indexIn(contents,pos)) != -1 ) {
134 contents.replace(pos,constructFilter.matchedLength(),
"(QObject* "+constructFilter.cap(1)
135 +
"=0) : " + constructFilter.cap(3) +
"(" + constructFilter.cap(1) +
")" );
139 constructFilter.setPattern(
"[(]\\s*QObject\\s*\\*\\s*(\\w*)\\s*=\\s*0\\s*,\\s*const\\s*char\\s*\\*\\s*(\\w*)\\s*=\\s*0\\s*[)]");
142 while ((pos = constructFilter.indexIn(contents,pos)) != -1 ) {
143 contents.replace(pos,constructFilter.matchedLength(),
"(QObject* "+constructFilter.cap(1)+
"=0)");
148 std::cout <<
"Modifying " << qPrintable(fileName) << std::endl;
153 QFile output(fileName);
154 if (! output.open(QIODevice::WriteOnly))
156 std::cerr <<
"Failed to write " << qPrintable(fileName) << std::endl;
159 QTextStream(&output) << contents ;
164 void processCppSource(QString fileName)
167 QFile input(fileName);
168 if (!input.open(QIODevice::ReadOnly))
170 std::cerr <<
"Failed to read " << qPrintable(fileName) << std::endl;
173 QString contents = QTextStream(&input).readAll();
176 QRegExp constructFilter(
"[(]\\s*QObject\\s*\\*\\s*(\\w*)\\s*,\\s*const\\s*char\\s*\\*\\s*(\\w*)\\s*[)]\\s*:\\s*(\\w*)\\s*[(]\\s*\\1\\s*,\\s*\\2\\s*[)]");
177 constructFilter.setMinimal(
true);
181 while ((pos = constructFilter.indexIn(contents,pos)) != -1 ) {
182 contents.replace(pos,constructFilter.matchedLength(),
"(QObject* "+constructFilter.cap(1)
183 +
") : " + constructFilter.cap(3) +
"(" + constructFilter.cap(1) +
")" );
187 std::cout <<
"Modifying " << qPrintable(fileName) << std::endl;
192 QFile output(fileName);
193 if (! output.open(QIODevice::WriteOnly))
195 std::cerr <<
"Failed to write " << qPrintable(fileName) << std::endl;
198 QTextStream(&output) << contents ;
203 void portLibraryFile(QString fileName,QString outName= QString::null)
205 QFile input(fileName);
206 if (!input.open(QIODevice::ReadOnly))
208 QString contents = QTextStream(&input).readAll();
212 QDomElement root = doc.createElement(
"library");
213 doc.appendChild(root);
214 QDomElement headers = doc.createElement(
"headers");
215 QDomElement components = doc.createElement(
"components");
216 root.appendChild(headers);
217 root.appendChild(components);
220 QRegExp regExp(
"#include\\s*\"(.+)\"");
221 regExp.setMinimal(
true);
223 while ((pos = regExp.indexIn(contents, pos)) != -1) {
224 QDomElement header = doc.createElement(
"header");
225 header.setAttribute(
"name", regExp.cap(1));
226 headers.appendChild(header);
227 pos += regExp.matchedLength();
231 regExp.setPattern(
"METALIB_OBJECT\\s*[(](.+)[)]");
233 while ((pos = regExp.indexIn(contents, pos)) != -1) {
234 QDomElement component = doc.createElement(
"component");
235 component.setAttribute(
"name", regExp.cap(1));
236 components.appendChild(component);
237 pos += regExp.matchedLength();
242 if (!outName.isEmpty())
244 output=
new QFile(outName);
245 if (! output->open(QIODevice::WriteOnly) )
247 std::cerr <<
"Could not create ARCS2 libfile " << qPrintable(outName) << std::endl;
253 output =
new QFile();
254 if(!output->open(1,QIODevice::WriteOnly))
256 std::cerr <<
"Could not open stdout ?!?" << std::endl;
261 QTextStream ts(output);
268 void portApplicationFile(QString fileName)
271 QFileInfo fi(fileName);
272 QFile file(fi.baseName()+
".arcs2."+fi.suffix());
273 query.bindVariable(
"file",QVariant(QDir::currentPath()+ QDir::separator()+fileName));
274 query.setQuery(QUrl(
"qrc:///arcsapp1to2.xq"),QDir::currentPath());
275 file.open(QIODevice::WriteOnly);
276 QXmlFormatter fmt(query, &file);
277 query.evaluateTo(&fmt);
282 void portComponentFile(QString fileName)
285 QFileInfo fi(fileName);
286 QFile file(fi.baseName()+
".arcs2."+fi.suffix());
287 query.bindVariable(
"file",QVariant(QDir::currentPath()+ QDir::separator()+fileName));
288 query.setQuery(QUrl(
"qrc:///arcscmp1to2.xq"),QDir::currentPath());
289 file.open(QIODevice::WriteOnly);
290 QXmlFormatter fmt(query, &file);
291 query.evaluateTo(&fmt);
296 void portProjectFile(QString fileName)
298 std::cout <<
"Porting from Qt3 to Qt4" << std::endl;
299 std::cout <<
"============================================" << std::endl;
304 QTemporaryFile* portFile= QTemporaryFile::createLocalFile(
":/q3porting_arcs.xml");
308 process.setProcessChannelMode(QProcess::ForwardedChannels);;
310 args <<
"-rulesFile" <<portFile->fileName() <<
"-alwaysOverwrite" << fileName ;
311 process.start(
"qt3to4",args );
313 process.waitForFinished(-1);
316 std::cout <<
"============================================" << std::endl << std::endl;
317 std::cout <<
"Porting from ARCS1 to ARCS2" << std::endl;
318 std::cout <<
"============================================" << std::endl;
324 QFile input(fileName);
325 if (!input.open(QIODevice::ReadOnly))
327 QString project = QTextStream(&input).readAll();
332 project.insert(0,
"# Project modified by ARCS1to2\n\n");
335 QRegExp regexp(
"\\bTARGET\\s*=\\s*(\\w+)\\b");
336 regexp.setMinimal(
true);
337 int pos=regexp.indexIn(project);
339 target= regexp.cap(1);
341 if (target.isEmpty())
342 target=QFileInfo(fileName).baseName();
343 std::cout <<
"Target is " << qPrintable(target) << std::endl;
347 QStringList cppSources=capList(
"\\s*(\\w+[.]cpp)\\s*",project);
348 for (
int i=0; i < cppSources.count(); i++)
350 if( isLibraryFile(cppSources[i]))
352 std::cout << qPrintable(cppSources[i]) <<
" is the library file !"<< std::endl;
353 project.replace(QRegExp(
"\\b"+cppSources[i]+
"\\b"),
"");
354 QString alxFile =
"lib"+QFileInfo(fileName).baseName()+
".alx";
355 portLibraryFile(cppSources[i], alxFile);
356 project.append(qmake_append.replace(
"@",alxFile));
360 processCppSource(cppSources[i]);
364 QStringList headers = capList(
"\\s*(\\w+[.]h)\\s*",project);
365 for (
int i=0; i< headers.count(); i++)
367 processHeader(headers[i]);
370 project.append(qmake_preamble);
372 std::cout <<
"============================================" << std::endl << std::endl;
373 std::cout <<
"Writing down final project file" << std::endl;
375 QFile output(fileName);
376 if (!output.open(QIODevice::WriteOnly))
378 std::cerr <<
"Cannot write down final project file " << std::endl;
382 QTextStream(&output) << project ;
391 bool parseOptions(
int argc,
char* argv[])
393 for (
int i=1; i < argc; i++)
395 QString current(argv[i]);
397 portApplicationFile(argv[++i]);
401 portComponentFile(argv[++i]);
405 portLibraryFile(argv[++i]);
408 portProjectFile(argv[++i]);
418 void usage(
char* name)
420 std::cout <<
"Usage: " << name <<
" (-a|-c|-l|-p) filename " << std::endl;
421 std::cout <<
"\t -a stands for application files in XML format;" << std::endl;
422 std::cout <<
"\t -c stands for composite component files in XML format;" << std::endl;
423 std::cout <<
"\t -l stands for library files in CPP format;" << std::endl;
424 std::cout <<
"\t -p stands for project files in pro format;" << std::endl;
429 int main(
int argc,
char* argv[])
431 QCoreApplication app(argc,argv);
432 std::cout << argv[0] <<
", a porting tool from ARCS1 to ARCS2" << std::endl;
440 if (!parseOptions(argc,argv))