cd woc && $(QMAKE) CONFIG+=woc
$(MAKE) -C woc
-qtbase:
+qtbase: woc
cd qtbase && $(QMAKE)
$(MAKE) -C qtbase
With both Qt bases outputs you can optionally specify a <tt>shareObjects</tt> attribute - if present it contains the class prefix for communication objects. If that prefix is different from the one given as <tt>classPrefix</tt> woc will assume that some other output will create those objects and not create them in this output. This feature is meant for the case in which client and server reside in the same translation unit and share the same objects (transactions and interfaces can unfortunately not be shared).<p>
+Another optional attribute is <tt>enableExport</tt> - set it to "yes" to enable export of the generated symbols in case you compile them into a DLL and want users of that DLL to be able to use the generated classes in their code. Set it to "no" to hide those symbols ("no" is the default).<p>
+
The PHPServerOutput tag tells woc to create a generator for a PHP based server. The "extension" attribute tells woc which file extension to use for the generated files (default is .php). Woc will automatically create a "autoload" (plus extension) file that should be included from the main body of the PHP project to load the automatically generated classes. The <tt>transactionBase</tt> attribute allows to chose an extended class as base class of generated transactions - it is recommended to overwrite some protected functions in order to be able to get more information inside transactions.<p>
The HtmlOutput tag tells woc where to generate API documentation. This target generates generic high level documentation for all configured tables, classes, and transactions. Use doxygen or a similar tool to generate language target specific documentation.<p>
#include <QString>
-class WException
+#ifndef WOLF_BASE_EXPORT
+#define WOLF_BASE_EXPORT Q_DECL_IMPORT
+#endif
+
+class WOLF_BASE_EXPORT WException
{
protected:
WException(QString e,QString c){err=e;comp=c;}
class QDomElement;
class QDomNode;
-class WHelper:public QObject
+#ifndef WOLF_BASE_EXPORT
+#define WOLF_BASE_EXPORT Q_DECL_IMPORT
+#endif
+
+class WOLF_BASE_EXPORT WHelper:public QObject
{
protected:
/**helper for de-serializers: returns direct child elements with given tag name (necessary because QDomElement::elementsByTagName traverses all children)*/
class WServerRequest;
class WServerReply;
+#ifndef WOLF_BASE_EXPORT
+#define WOLF_BASE_EXPORT Q_DECL_IMPORT
+#endif
+
/// base class of all interfaces
-class WInterface:public QObject
+class WOLF_BASE_EXPORT WInterface:public QObject
{
Q_OBJECT
Q_PROPERTY(QUrl url READ url)
#ifndef WOLF_NULLABLE_H
#define WOLF_NULLABLE_H
+#ifndef WOLF_BASE_EXPORT
+#define WOLF_BASE_EXPORT Q_DECL_IMPORT
+#endif
+
///special class for Null values
-class NullValue
+class WOLF_BASE_EXPORT NullValue
{
public:
NullValue(){}
const NullValue nullval;
/**wrapper around scalar values that makes them NULL-able, i.e. the virtual value NULL is added to the range of the wrapped value; wrapped classes must have a default constructor and =, == and != operators*/
-template<class T>class Nullable
+template<class T>class WOLF_BASE_EXPORT Nullable
{
public:
/**creates a NULL value*/
Q_DECLARE_METATYPE(Nullable<QString>)
Q_DECLARE_METATYPE(Nullable<QByteArray>)
-inline bool operator==(Nullable<qint64> i1,int i2){return i1.operator==(i2);}
-inline bool operator==(Nullable<quint32> i1,int i2){return i1.operator==(i2);}
-inline bool operator==(Nullable<quint64> i1,int i2){return i1.operator==(i2);}
-inline bool operator==(Nullable<quint64> i1,unsigned int i2){return i1.operator==(i2);}
+inline WOLF_BASE_EXPORT bool operator==(Nullable<qint64> i1,int i2){return i1.operator==(i2);}
+inline WOLF_BASE_EXPORT bool operator==(Nullable<quint32> i1,int i2){return i1.operator==(i2);}
+inline WOLF_BASE_EXPORT bool operator==(Nullable<quint64> i1,int i2){return i1.operator==(i2);}
+inline WOLF_BASE_EXPORT bool operator==(Nullable<quint64> i1,unsigned int i2){return i1.operator==(i2);}
#endif
class QScriptEngine;
/**base class of all web based objects*/
-class WObject:public WHelper
+class WOLF_BASE_EXPORT WObject:public WHelper
{
protected:
WObject(){}
};
/**this exception is thrown if the deserialization of an object fails on the XML parser level*/
-class WDeserializerException:public WException
+class WOLF_BASE_EXPORT WDeserializerException:public WException
{
public:
WDeserializerException(QString e):WException(e,"Deserializer"){}
class QLocalServer;
class WInterface;
+#ifndef WOLF_BASE_EXPORT
+#define WOLF_BASE_EXPORT Q_DECL_IMPORT
+#endif
+
///Encapsulates the request as it comes in via (S)CGI
-class WServerRequest
+class WOLF_BASE_EXPORT WServerRequest
{
public:
///instantiates an empty request
Q_DECLARE_METATYPE(WServerRequest);
///reply object for the server side: contains the data sent back to the client
-class WServerReply
+class WOLF_BASE_EXPORT WServerReply
{
public:
///creates an invalid reply (500 Server Error)
*
* Use the cgi2scgi helper to translate between CGI and SCGI.
*/
-class WServer:public QObject
+class WOLF_BASE_EXPORT WServer:public QObject
{
Q_OBJECT
public:
class WTransaction_Private;
/**base class of all transactions*/
-class WTransaction:public WHelper
+class WOLF_BASE_EXPORT WTransaction:public WHelper
{
Q_OBJECT
Q_ENUMS(Stage)
WTransaction*parent;
};
-class WTransaction_PrivateBase {
+class WOLF_BASE_EXPORT WTransaction_PrivateBase {
private:
int refctr;
protected:
TEMPLATE = lib
TARGET = qwbase
DESTDIR = ../qtbase
-CONFIG += dll create_prl separate_debug_info
+CONFIG += dll create_prl separate_debug_info hide_symbols
QT += xml network
QT -= gui
OBJECTS_DIR = .ctmp
MOC_DIR = .ctmp
RCC_DIR = .ctmp
+#no version info yet, TODO: fixme
VERSION =
+#make sure symbols are exported:
+DEFINES += WOLF_BASE_EXPORT=Q_DECL_EXPORT
+
HEADERS += \
include/nullable.h \
include/helper.h \
//lead in
hdr.write(QByteArray(HDRSTART).replace("%",cna.toLatin1()));
src.write(QByteArray(SRCSTART).replace("%",cna.toLatin1()));
+ hdr.write(m_parent->exportLines());
QString hcd;
QString scd;
//class declaration
QString cnb=cls.baseClass(m_parent->languageSpec(),m_parent->namePrefix()+"O");
hcd+=doxyFormat(cls.docStrings());
- hcd+="class "+cna+":public "+cnb+"\n{\n Q_OBJECT\n";
+ hcd+="class "+m_parent->exportSymbol()+" "+cna+":public "+cnb+"\n{\n Q_OBJECT\n";
hdr.write(hcd.toLatin1());
//enums
//lead in
hdr.write(QByteArray(HDRSTART).replace("%",cn.toLatin1()));
src.write(QByteArray(SRCSTART).replace("%",cn.toLatin1()));
+ hdr.write(m_parent->exportLines());
//start constructing code
//start of class
ct.hcd+="\nclass "+cnp+";\n";
ct.hcd+="\n"+doxyFormat(trn.docStrings());
- ct.hcd+="class "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n";
+ ct.hcd+="class "+m_parent->exportSymbol()+" "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n";
ct.pcd+="\nclass "+cnp+":public WTransaction_PrivateBase\n{\n";
//create properties
m_cprefix=el.attribute("shareObjects",m_prefix);
m_transbase=el.attribute("transactionBase","WTransaction");
m_genscript=str2bool(el.attribute("scriptable","0"));
+ m_export=str2bool(el.attribute("enableExport","0"));
//get/create directory
QDir d(m_basedir+"/"+m_subdir);
if(!d.exists())QDir(".").mkpath(m_basedir+"/"+m_subdir);
}
m_pri.write(QByteArray("#AUTOMATICALLY GENERATED FILE - DONT CHANGE!\n"));
m_pri.write(QByteArray("INCLUDEPATH += ")+m_subdir.toLatin1()+QByteArray("\n"));
+ if(m_export)
+ m_pri.write(QByteArray("DEFINES += ")+exportSymbol().toLatin1()+QByteArray("=Q_DECL_EXPORT\n"));
//create interface class
WocProcessor*woc=WocProcessor::instance();
m_iface.write(QByteArray(HDRSTART).replace("%",m_prefix.toLatin1()+"INTERFACE_H"));
m_iface.write(QByteArray("#include \"WInterface\"\n"));
m_iface.write(QByteArray("#include <QStringList>\n"));
+ m_iface.write(exportLines());
if(m_genscript)
- m_iface.write(QByteArray("class QScriptEngine;\n"));
+ m_iface.write(QByteArray("class ")+exportSymbol().toLatin1()+QByteArray(" QScriptEngine();\n"));
addIfaceHeaderClass(doxyFormat(pn+" interface class."));
- addIfaceHeaderClass(QString("class "+ifaceClassName()+":public WInterface\n{\n Q_OBJECT\n"));
+ addIfaceHeaderClass(QString("class "+exportSymbol()+" "+ifaceClassName()+":public WInterface\n{\n Q_OBJECT\n"));
addIfaceHeaderClass(QString(" public:\n "+ifaceClassName()+"(QString name=\""+pn+"\"):WInterface(name){}\n"));
addIfaceHeaderClass(" /// convenience override: returns a pointer to an instance with the given name if it is of the correct type, otherwise nullptr\n");
addIfaceHeaderClass(" static "+ifaceClassName()+"*instance(QString name=\""+pn+"\")\n\t{return qobject_cast<"+ifaceClassName()+"*>(WInterface::instance(name));}\n\n");
{
m_ifacecpp.write(s.toLatin1());
}
+
+QByteArray WocQtOut::exportLines() const
+{
+ if(!m_export)return QByteArray();
+ QByteArray ret="\n#ifndef "+exportSymbol().toLatin1()+
+ "\n#define "+exportSymbol().toLatin1()+" Q_DECL_IMPORT\n"
+ "#endif\n\n";
+ return ret;
+}
+
+QString WocQtOut::exportSymbol() const
+{
+ if(!m_export)return QString();
+ if(m_exportsym.isEmpty()){
+ m_exportsym="WOBGEN_";
+ QString r=WocProcessor::instance()->projectName();
+ r+="_"+m_subdir;
+ for(auto c:r.toUpper()){
+ if(c>='A' && c<='Z')m_exportsym+=c;
+ else if(c=='_')m_exportsym+="__";
+ else m_exportsym+="_"+QString::number((unsigned char)c.toLatin1(),16);
+ }
+ m_exportsym+="_EXPORT";
+ }
+ return m_exportsym;
+}
///returns the base class of all transactions
inline QString transactionBase()const{return m_transbase;}
+ ///returns some lines of code to define an export symbol
+ QByteArray exportLines()const;
+ ///returns the name of the preprocessor symbol used for export
+ QString exportSymbol()const;
+
private:
///internal: init the scripting env
void initScripting();
private:
QString m_basedir,m_subdir,m_prefix,m_cprefix,m_transbase,m_postiface,m_scriptcode;
- bool m_clean,m_genscript;
+ mutable QString m_exportsym;
+ bool m_clean,m_genscript,m_export;
MFile m_pri,m_iface,m_ifacecpp,m_hdr;
QString m_iface_prefix,m_iface_class;
protected:
//lead in
hdr.write(QByteArray(HDRSTART).replace("%",cn.toLatin1()));
src.write(QByteArray(SRCSTART).replace("%",cn.toLatin1()));
+ hdr.write(m_parent->exportLines());
//start constructing code
genInclude(ct);
//start of class
ct.hcd+="\nclass "+cnp+";\n";
- ct.hcd+="\nclass "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n";
+ ct.hcd+="\nclass "+m_parent->exportSymbol()+" "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n";
ct.pcd+="\nclass "+cnp+":public WTransaction_PrivateBase\n{\n";
//create properties