--- /dev/null
+//
+// C++ Implementation: mfile
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2010
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "mfile.h"
+
+#include <QFileInfo>
+
+//static
+QMap<QString,QStringList> MFile::touched;
+
+MFile::MFile(QString n,QObject*parent):QFile(n+",new",parent),name(n){isopen=false;}
+MFile::MFile(QObject *parent):QFile(parent){isopen=false;}
+MFile::~MFile()
+{
+ if(isopen)close();
+}
+
+void MFile::close()
+{
+// qDebug("Info: closing %s",name.toAscii().data());
+ //compare
+ bool ident=false;
+ if(isopen){
+ QFile::close();
+ QFile::open(QIODevice::ReadOnly);
+ QByteArray here=readAll();
+ QFile there(name);
+ if(there.open(QIODevice::ReadOnly)){
+ ident=(here == there.readAll());
+ there.close();
+ }
+ }
+ //actual close
+ QFile::close();
+ //move
+ if(isopen){
+ isopen=false;
+ if(ident){
+ //if identical: remove new version to preserve file time
+ remove();
+ }else{
+ //if not identical: use new version, remove old one
+ QFile(name).remove();
+ QFile(name+",new").rename(name);
+ }
+ }
+}
+
+void MFile::setFileName(QString n)
+{
+ name=n;
+ QFile::setFileName(n+",new");
+}
+
+bool MFile::open(QIODevice::OpenMode m)
+{
+ isopen=QFile::open(m);
+ if(isopen){
+ //remember it
+ QFileInfo fi(name);
+ QString p=fi.absolutePath();
+ QString f=fi.fileName();
+ if(!touched.contains(p))touched.insert(p,QStringList());
+ if(!touched[p].contains(f))touched[p]<<f;
+ }
+ return isopen;
+}
+
+bool MFile::touchedFile(QString name)
+{
+ QFileInfo fi(name);
+ QString p=fi.absolutePath();
+ QString f=fi.fileName();
+ if(!touched.contains(p))return false;
+ return touched[p].contains(f);
+}
--- /dev/null
+//
+// C++ Interface: mfile
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2010
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef WOC_MFILE_H
+#define WOC_MFILE_H
+
+#include <QFile>
+#include <QMap>
+#include <QStringList>
+
+/**overwrites QFile to only generate a file if its new version differs from an existing one, it creates a temporary file with ",new" added to the file name; additionally it records all file names that it touches;
+this is not a complete implementation - just enough for woc*/
+class MFile:public QFile
+{
+ public:
+ MFile(QString name,QObject*parent=0);
+ MFile(QObject *parent=0);
+ ~MFile();
+
+ virtual void close();
+ virtual bool open(QIODevice::OpenMode m);
+
+ QString fileName()const{return name;}
+ void setFileName(QString n);
+
+ static bool touchedFile(QString);
+ private:
+ //flag to show whether file is open
+ bool isopen;
+ //original name of the file
+ QString name;
+
+ //stores touched files
+ static QMap<QString,QStringList> touched;
+};
+
+#endif
qDebug("Info: creating Qt Client Output Generator.");
m_basedir=WocProcessor::instance()->baseDir()+"/"+el.attribute("sourceDir",".");
m_subdir=el.attribute("subDir","qtwob");
- bool clean=str2bool(el.attribute("clean","0"));
+ m_clean=str2bool(el.attribute("clean","0"));
m_prefix=el.attribute("classPrefix","Wob");
- //cleanup directory (remove normal files, assume remainder is harmless)
- QDir d(m_basedir+"/"+m_subdir);
- if(d.exists() && clean){
- QStringList ent=d.entryList(QDir::Files);
- for(int i=0;i<ent.size();i++)
- d.remove(ent[i]);
- }
//get/create directory
+ QDir d(m_basedir+"/"+m_subdir);
if(!d.exists())QDir(".").mkpath(m_basedir+"/"+m_subdir);
//create project file
m_pri.close();
m_hdr.write(HDREND);
m_hdr.close();
+ //cleanup directory (remove untouched normal files, assume remainder is harmless)
+ QDir d(m_basedir+"/"+m_subdir);
+ if(m_clean){
+ QStringList ent=d.entryList(QDir::Files);
+ for(int i=0;i<ent.size();i++)
+ if(!MFile::touchedFile(m_basedir+"/"+m_subdir+"/"+ent[i])){
+ qDebug("Info: removing old file %s",ent[i].toAscii().data());
+ d.remove(ent[i]);
+ }
+ }
}
void WocQtClientOut::newTable(const WocTable&){/*not needed, Qt client is a few levels higher*/}
QString cna=cn;
if(cls.isAbstract("qt"))cna+="Abstract";
addFile(cna);
- QFile hdr(m_basedir+"/"+m_subdir+"/"+cna+".h");
- QFile src(m_basedir+"/"+m_subdir+"/"+cna+".cpp");
+ MFile hdr(m_basedir+"/"+m_subdir+"/"+cna+".h");
+ MFile src(m_basedir+"/"+m_subdir+"/"+cna+".cpp");
if(!hdr.open(QIODevice::WriteOnly|QIODevice::Truncate) ||
!src.open(QIODevice::WriteOnly|QIODevice::Truncate)){
qDebug("Error: cannot create class files for class %s.",cn.toAscii().data());
src.write(QByteArray(SRCEND).replace("%",cna.toAscii()));
}
-void WocQtClientOut::classEnums(const WocClass&cls,QFile&hdr,QFile&src,QString cn)
+void WocQtClientOut::classEnums(const WocClass&cls,MFile&hdr,MFile&src,QString cn)
{
QStringList k=cls.enumTypes();
if(k.size()==0)return;
src.write(scd.toAscii());
}
-void WocQtClientOut::classProperties(const WocClass&cls,QFile&hdr,QFile&)
+void WocQtClientOut::classProperties(const WocClass&cls,MFile&hdr,MFile&)
{
QStringList k=cls.propertyNames();
if(k.size()==0)return;
return r;
}
-void WocQtClientOut::classDeserializer(const WocClass&cls,QFile&hdr,QFile&src,QString cn)
+void WocQtClientOut::classDeserializer(const WocClass&cls,MFile&hdr,MFile&src,QString cn)
{
QString hcd,scd;
hcd=" public:\n";
src.write(scd.toAscii());
}
-void WocQtClientOut::classSerializers(const WocClass&cls,QFile&hdr,QFile&src,QString cn)
+void WocQtClientOut::classSerializers(const WocClass&cls,MFile&hdr,MFile&src,QString cn)
{
QString hcd=" public:\n";
QString scd;
{
QString cn=m_prefix+"T"+trn.name();
addFile(cn);
- QFile hdr(m_basedir+"/"+m_subdir+"/"+cn+".h");
- QFile src(m_basedir+"/"+m_subdir+"/"+cn+".cpp");
+ MFile hdr(m_basedir+"/"+m_subdir+"/"+cn+".h");
+ MFile src(m_basedir+"/"+m_subdir+"/"+cn+".cpp");
if(!hdr.open(QIODevice::WriteOnly|QIODevice::Truncate) ||
!src.open(QIODevice::WriteOnly|QIODevice::Truncate)){
qDebug("Error: cannot create class files for transaction %s.",cn.toAscii().data());
#include "processor.h"
-#include <QFile>
+#include "mfile.h"
class QDomElement;
virtual void newTransaction(const WocTransaction&);
private:
QString m_basedir,m_subdir,m_prefix;
- QFile m_pri,m_iface,m_ifacecpp,m_hdr;
+ MFile m_pri,m_iface,m_ifacecpp,m_hdr;
+ bool m_clean;
/**helper: adds a file to the project file*/
void addFile(QString basename);
/**helper: generate enums for classes*/
- void classEnums(const WocClass&,QFile&,QFile&,QString);
+ void classEnums(const WocClass&,MFile&,MFile&,QString);
/**helper: generate properties*/
- void classProperties(const WocClass&,QFile&,QFile&);
+ void classProperties(const WocClass&,MFile&,MFile&);
/**helper: generate constructors/deserializer/copiers*/
- void classDeserializer(const WocClass&,QFile&,QFile&,QString);
+ void classDeserializer(const WocClass&,MFile&,MFile&,QString);
/**helper: generate serializers*/
- void classSerializers(const WocClass&,QFile&,QFile&,QString);
+ void classSerializers(const WocClass&,MFile&,MFile&,QString);
/**helper: generate a proper Qt type for a property*/
QString qttype(const WocClass&,QString,bool dolist=true);
qtout.cpp \
phpout.cpp \
htmlout.cpp \
+ mfile.cpp \
../src/misc/domquery.cpp
HEADERS+= \
processor.h \
phpout.h \
qtout.h \
htmlout.h \
+ mfile.h \
../src/misc/domquery.h
INCLUDEPATH += ../src/misc
\ No newline at end of file