modified woc to only write Qt output if it actually changed
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Fri, 1 Jan 2010 12:32:34 +0000 (12:32 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Fri, 1 Jan 2010 12:32:34 +0000 (12:32 +0000)
git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@384 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

woc/mfile.cpp [new file with mode: 0644]
woc/mfile.h [new file with mode: 0644]
woc/qtout.cpp
woc/qtout.h
woc/woc.pro

diff --git a/woc/mfile.cpp b/woc/mfile.cpp
new file mode 100644 (file)
index 0000000..e6c0c9a
--- /dev/null
@@ -0,0 +1,85 @@
+//
+// 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);
+}
diff --git a/woc/mfile.h b/woc/mfile.h
new file mode 100644 (file)
index 0000000..44a3d38
--- /dev/null
@@ -0,0 +1,46 @@
+//
+// 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
index 53a336b..1d9bbf1 100644 (file)
@@ -40,16 +40,10 @@ WocQtClientOut::WocQtClientOut(QDomElement&el)
        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
@@ -114,6 +108,16 @@ void WocQtClientOut::finalize()
        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*/}
@@ -124,8 +128,8 @@ void WocQtClientOut::newClass(const WocClass&cls)
        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());
@@ -167,7 +171,7 @@ void WocQtClientOut::newClass(const WocClass&cls)
        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;
@@ -220,7 +224,7 @@ void WocQtClientOut::classEnums(const WocClass&cls,QFile&hdr,QFile&src,QString c
        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;
@@ -263,7 +267,7 @@ QString WocQtClientOut::qttype(const WocClass&cls,QString p,bool dolist)
        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";
@@ -380,7 +384,7 @@ void WocQtClientOut::classDeserializer(const WocClass&cls,QFile&hdr,QFile&src,QS
        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;
@@ -477,8 +481,8 @@ void WocQtClientOut::newTransaction(const WocTransaction&trn)
 {
        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());
index 873e7ae..281fce6 100644 (file)
@@ -15,7 +15,7 @@
 
 #include "processor.h"
 
-#include <QFile>
+#include "mfile.h"
 
 class QDomElement;
 
@@ -31,18 +31,19 @@ class WocQtClientOut:public WocOutput
                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);
                
index e9ffd33..e04bdbd 100644 (file)
@@ -17,12 +17,14 @@ SOURCES+= \
        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