summaryrefslogtreecommitdiffstats
path: root/tqt3integration/utils/gen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqt3integration/utils/gen.cpp')
-rw-r--r--tqt3integration/utils/gen.cpp970
1 files changed, 970 insertions, 0 deletions
diff --git a/tqt3integration/utils/gen.cpp b/tqt3integration/utils/gen.cpp
new file mode 100644
index 000000000..178d67a3b
--- /dev/null
+++ b/tqt3integration/utils/gen.cpp
@@ -0,0 +1,970 @@
+ /*
+ * This file is part of the Trinity Desktop Environment
+ *
+ * Original file taken from the OpenSUSE kdebase builds
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qfile.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+#include <stdlib.h>
+
+// TODO includes, forwards
+
+
+/*
+
+FUNCTION <name>
+ RETURN_TYPE <type>
+ DELAYED_RETURN - use DCOP transaction in kded module, function will take some time to finish
+ SKIP_QT - don't generate in qt file
+ ONLY_QT - generate only in qt file
+ ADD_APPINFO - generate wmclass arguments
+ ARG <name>
+ TYPE <type>
+ ORIG_TYPE <type> - for example when the function accepts QWidget*, but WId is really used
+ ORIG_CONVERSION <conversion>
+ IGNORE
+ NEEDS_DEREF
+ CONST_REF
+ OUT_ARGUMENT
+ CONVERSION <function>
+ BACK_CONVERSION <function> - for out arguments
+ CREATE <function> - doesn't exist in Qt, create in qtkde using function
+ PARENT - the argument is a parent window to be used for windows
+ ENDARG
+ENDFUNCTION
+
+*/
+
+struct Arg
+ {
+ Arg() : ignore( false ), needs_deref( false ), const_ref( false ), out_argument( false ), parent( false ) {}
+ QString name;
+ QString type;
+ QString orig_type;
+ QString orig_conversion;
+ bool ignore;
+ bool needs_deref;
+ bool const_ref;
+ bool out_argument;
+ QString conversion;
+ QString back_conversion;
+ QString create;
+ bool parent;
+ };
+
+struct Function
+ {
+ Function() : delayed_return( false ), skip_qt( false ), only_qt( false ), add_appinfo( false ) {}
+ QString name;
+ QString return_type;
+ bool delayed_return;
+ bool skip_qt;
+ bool only_qt;
+ bool add_appinfo;
+ QValueList< Arg > args;
+ void stripNonOutArguments();
+ void stripCreatedArguments();
+ };
+
+void Function::stripNonOutArguments()
+ {
+ QValueList< Arg > new_args;
+ for( QValueList< Arg >::ConstIterator it = args.begin();
+ it != args.end();
+ ++it )
+ {
+ const Arg& arg = (*it);
+ if( arg.out_argument )
+ new_args.append( arg );
+ }
+ args = new_args;
+ }
+
+void Function::stripCreatedArguments()
+ {
+ QValueList< Arg > new_args;
+ for( QValueList< Arg >::ConstIterator it = args.begin();
+ it != args.end();
+ ++it )
+ {
+ const Arg& arg = (*it);
+ if( arg.create.isEmpty())
+ new_args.append( arg );
+ }
+ args = new_args;
+ }
+
+QValueList< Function > functions;
+
+QFile* input_file = NULL;
+QTextStream* input_stream = NULL;
+static QString last_line;
+int last_lineno = 0;
+
+#define check( arg ) my_check( __FILE__, __LINE__, arg )
+#define error() my_error( __FILE__, __LINE__ )
+
+void my_error( const char* file, int line )
+ {
+ fprintf( stderr, "Error: %s: %d\n", file, line );
+ fprintf( stderr, "Line %d: %s\n", last_lineno, last_line.utf8().data());
+ abort();
+ }
+
+void my_check( const char* file, int line, bool arg )
+ {
+ if( !arg )
+ my_error( file, line );
+ }
+
+void openInputFile( const QString& filename )
+ {
+ check( input_file == NULL );
+ input_file = new QFile( filename );
+ printf("[INFO] Reading bindings definitions from file %s\n\r", filename.ascii());
+ if( !input_file->open( IO_ReadOnly ))
+ error();
+ input_stream = new QTextStream( input_file );
+ last_lineno = 0;
+ }
+
+QString getInputLine()
+ {
+ while( !input_stream->atEnd())
+ {
+ QString line = input_stream->readLine().stripWhiteSpace();
+ ++last_lineno;
+ last_line = line;
+ if( line.isEmpty() || line[ 0 ] == '#' )
+ continue;
+ return line;
+ }
+ return QString::null;
+ }
+
+void closeInputFile()
+ {
+ delete input_stream;
+ delete input_file;
+ input_stream = NULL;
+ input_file = NULL;
+ }
+
+void parseArg( Function& function, const QString& details )
+ {
+ Arg arg;
+ arg.name = details;
+ QString line = getInputLine();
+ while( !line.isNull() )
+ {
+ if( line.startsWith( "ENDARG" ))
+ {
+ check( !arg.type.isEmpty());
+ function.args.append( arg );
+ return;
+ }
+ else if( line.startsWith( "TYPE" ))
+ {
+ check( arg.type.isEmpty());
+ arg.type = line.mid( strlen( "TYPE" )).stripWhiteSpace();
+ }
+ else if( line.startsWith( "ORIG_TYPE" ))
+ {
+ check( arg.orig_type.isEmpty());
+ arg.orig_type = line.mid( strlen( "ORIG_TYPE" )).stripWhiteSpace();
+ }
+ else if( line.startsWith( "ORIG_CONVERSION" ))
+ {
+ check( arg.orig_conversion.isEmpty());
+ arg.orig_conversion = line.mid( strlen( "ORIG_CONVERSION" )).stripWhiteSpace();
+ }
+ else if( line.startsWith( "IGNORE" ))
+ {
+ check( !arg.out_argument );
+ arg.ignore = true;
+ }
+ else if( line.startsWith( "NEEDS_DEREF" ))
+ {
+ check( !arg.const_ref );
+ arg.needs_deref = true;
+ }
+ else if( line.startsWith( "CONST_REF" ))
+ {
+ check( !arg.needs_deref );
+ check( !arg.out_argument );
+ arg.const_ref = true;
+ }
+ else if( line.startsWith( "OUT_ARGUMENT" ))
+ {
+ check( !arg.ignore );
+ check( !arg.const_ref );
+ arg.out_argument = true;
+ }
+ else if( line.startsWith( "CONVERSION" ))
+ {
+ check( arg.conversion.isEmpty());
+ arg.conversion = line.mid( strlen( "CONVERSION" )).stripWhiteSpace();
+ }
+ else if( line.startsWith( "BACK_CONVERSION" ))
+ {
+ check( arg.back_conversion.isEmpty());
+ arg.back_conversion = line.mid( strlen( "BACK_CONVERSION" )).stripWhiteSpace();
+ }
+ else if( line.startsWith( "CREATE" ))
+ {
+ check( arg.create.isEmpty());
+ arg.create = line.mid( strlen( "CREATE" )).stripWhiteSpace();
+ }
+ else if( line.startsWith( "PARENT" ))
+ {
+ arg.parent = true;
+ }
+ else
+ error();
+ line = getInputLine();
+ }
+ error();
+ }
+
+void parseFunction( const QString& details )
+ {
+ Function function;
+ function.name = details;
+ QString line = getInputLine();
+ while( !line.isNull() )
+ {
+ if( line.startsWith( "ENDFUNCTION" ))
+ {
+ if( function.add_appinfo )
+ {
+ Arg arg;
+ arg.name = "wmclass1";
+ arg.type = "QCString";
+ arg.const_ref = true;
+ arg.create = "qAppName";
+ function.args.append( arg );
+ arg.name = "wmclass2";
+ arg.create = "qAppClass";
+ function.args.append( arg );
+ }
+ check( !function.return_type.isEmpty());
+ functions.append( function );
+ return;
+ }
+ else if( line.startsWith( "RETURN_TYPE" ))
+ {
+ check( function.return_type.isEmpty());
+ function.return_type = line.mid( strlen( "RETURN_TYPE" )).stripWhiteSpace();
+ }
+ else if( line.startsWith( "DELAYED_RETURN" ))
+ function.delayed_return = true;
+ else if( line.startsWith( "SKIP_QT" ))
+ function.skip_qt = true;
+ else if( line.startsWith( "ONLY_QT" ))
+ function.only_qt = true;
+ else if( line.startsWith( "ADD_APPINFO" ))
+ function.add_appinfo = true;
+ else if( line.startsWith( "ARG" ))
+ {
+ parseArg( function, line.mid( strlen( "ARG" )).stripWhiteSpace());
+ }
+ else
+ error();
+ line = getInputLine();
+ }
+ error();
+ }
+
+void parse(TQString filename)
+ {
+ openInputFile( filename );
+ QString line = getInputLine();
+ while( !line.isNull() )
+ {
+ if( line.startsWith( "FUNCTION" ))
+ {
+ parseFunction( line.mid( strlen( "FUNCTION" )).stripWhiteSpace());
+ }
+ else
+ error();
+ line = getInputLine();
+ }
+ closeInputFile();
+ }
+
+QString makeIndent( int indent )
+ {
+ return indent > 0 ? QString().fill( ' ', indent ) : "";
+ }
+
+void generateFunction( QTextStream& stream, const Function& function, const QString name,
+ int indent, bool staticf, bool orig_type, bool ignore_deref, int ignore_level )
+ {
+ QString line;
+ line += makeIndent( indent );
+ if( staticf )
+ line += "static ";
+ line += function.return_type + " " + name + "(";
+ bool need_comma = false;
+ for( QValueList< Arg >::ConstIterator it = function.args.begin();
+ it != function.args.end();
+ ++it )
+ {
+ const Arg& arg = (*it);
+ if( ignore_level >= 2 && arg.ignore )
+ continue;
+ if( need_comma )
+ {
+ line += ",";
+ if( line.length() > 80 )
+ {
+ stream << line << "\n";
+ line = makeIndent( indent + 4 );
+ }
+ else
+ line += " ";
+ }
+ else
+ line += " ";
+ need_comma = true;
+ if( orig_type && !arg.orig_type.isEmpty())
+ line += arg.orig_type;
+ else
+ {
+ if( arg.const_ref )
+ line += "const ";
+ line += arg.type;
+ if( !ignore_deref && arg.needs_deref )
+ line += "*";
+ if( arg.const_ref )
+ line += "&";
+ }
+ if( ignore_level >= 1 && arg.ignore )
+ line += " /*" + arg.name + "*/";
+ else
+ line += " " + arg.name;
+ }
+ line += " )";
+ stream << line;
+ }
+
+void generateQtH()
+ {
+ QFile file( "qtkdeintegration_x11_p.h.gen" );
+ if( !file.open( IO_WriteOnly ))
+ error();
+ QTextStream stream( &file );
+ for( QValueList< Function >::ConstIterator it = functions.begin();
+ it != functions.end();
+ ++it )
+ {
+ Function f = *it;
+ if( f.skip_qt )
+ continue;
+ f.stripCreatedArguments();
+ generateFunction( stream, f, f.name, 8,
+ true /*static*/, true /*orig type*/, false /*ignore deref*/, 0 /*ignore level*/ );
+ stream << ";\n";
+ }
+ }
+
+void generateQtCpp()
+ {
+ QFile file( "qtkdeintegration_x11.cpp.gen" );
+ if( !file.open( IO_WriteOnly ))
+ error();
+ QTextStream stream( &file );
+ for( QValueList< Function >::ConstIterator it = functions.begin();
+ it != functions.end();
+ ++it )
+ {
+ Function f = *it;
+ if( f.only_qt )
+ continue;
+ f.stripCreatedArguments();
+ generateFunction( stream, f, "(*qtkde_" + f.name + ")", 0,
+ true /*static*/, false /*orig type*/, false /*ignore deref*/, 0 /*ignore level*/ );
+ stream << ";\n";
+ }
+ stream <<
+"\n"
+"void QKDEIntegration::initLibrary()\n"
+" {\n"
+" if( !inited )\n"
+" {\n"
+" enable = false;\n"
+" inited = true;\n"
+" QString libpath = findLibrary();\n"
+" if( libpath.isEmpty())\n"
+" return;\n"
+" QLibrary lib( libpath );\n"
+" if( !QFile::exists( lib.library())) // avoid stupid Qt warning\n"
+" return;\n"
+" lib.setAutoUnload( false );\n";
+ for( QValueList< Function >::ConstIterator it = functions.begin();
+ it != functions.end();
+ ++it )
+ {
+ Function function = *it;
+ if( function.only_qt )
+ continue;
+ stream << makeIndent( 8 ) + "qtkde_" + function.name + " = (\n";
+ function.stripCreatedArguments();
+ generateFunction( stream, function, "(*)", 12,
+ false /*static*/, false /*orig type*/, false /*ignore deref*/, 0 /*ignore level*/ );
+ stream << "\n" + makeIndent( 12 ) + ")\n";
+ stream << makeIndent( 12 ) + "lib.resolve(\"" + (*it).name + "\");\n";
+ stream << makeIndent( 8 ) + "if( qtkde_" + (*it).name + " == NULL )\n";
+ stream << makeIndent( 12 ) + "return;\n";
+ }
+ stream <<
+" enable = qtkde_initializeIntegration();\n"
+" }\n"
+" }\n"
+"\n";
+ for( QValueList< Function >::ConstIterator it1 = functions.begin();
+ it1 != functions.end();
+ ++it1 )
+ {
+ Function function = *it1;
+ if( function.skip_qt || function.only_qt )
+ continue;
+ function.stripCreatedArguments();
+ generateFunction( stream, function, "QKDEIntegration::" + function.name, 0,
+ false /*static*/, true /*orig type*/, false /*ignore deref*/, 0 /*ignore level*/ );
+ stream << "\n";
+ stream << makeIndent( 4 ) + "{\n";
+ stream << makeIndent( 4 ) + "return qtkde_" + function.name + "(\n";
+ stream << makeIndent( 8 );
+ bool need_comma = false;
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( need_comma )
+ stream << ", ";
+ need_comma = true;
+ if( !arg.orig_conversion.isEmpty())
+ {
+ stream << arg.orig_conversion + "( " + arg.name + " )";
+ }
+ else
+ stream << arg.name;
+ }
+ stream << " );\n";
+ stream << makeIndent( 4 ) + "}\n";
+ }
+ }
+
+void generateQt()
+ {
+ generateQtH();
+ generateQtCpp();
+ }
+
+void generateQtKde()
+ {
+ QFile file( "qtkde_functions.cpp" );
+ if( !file.open( IO_WriteOnly ))
+ error();
+ QTextStream stream( &file );
+ for( QValueList< Function >::ConstIterator it1 = functions.begin();
+ it1 != functions.end();
+ ++it1 )
+ {
+ const Function& function = *it1;
+ if( function.only_qt )
+ continue;
+ Function stripped_function = function;
+ stripped_function.stripCreatedArguments();
+ stream << "extern \"C\"\n";
+ generateFunction( stream, stripped_function, stripped_function.name, 0,
+ false /*static*/, false /*orig type*/, false /*ignore deref*/, 1 /*ignore level*/ );
+ stream << "\n";
+ stream <<
+" {\n"
+" if( qt_xdisplay() != NULL )\n"
+" XSync( qt_xdisplay(), False );\n";
+ QString parent_arg;
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.ignore )
+ continue;
+ if( arg.parent )
+ {
+ parent_arg = arg.name;
+ break;
+ }
+ }
+ if( !parent_arg.isEmpty())
+ {
+ stream << " if( " << parent_arg << " == 0 )\n";
+ stream << " DCOPRef( \"kded\", \"MainApplication-Interface\" ).call( \"updateUserTimestamp\", qt_x_time );\n";
+ }
+ stream <<
+" QByteArray data, replyData;\n"
+" QCString replyType;\n";
+ if( !function.args.isEmpty())
+ {
+ stream << " QDataStream datastream( data, IO_WriteOnly );\n";
+ stream << " datastream";
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.ignore )
+ continue;
+ stream << " << ";
+ if( !(arg.conversion).isNull() )
+ stream << arg.conversion + "( ";
+ if( !arg.create.isEmpty())
+ stream << arg.create + "()";
+ else
+ {
+ if( arg.needs_deref )
+ stream << "( " << arg.name << " != NULL ? *" << arg.name << " : " << arg.type << "())";
+ else
+ stream << arg.name;
+ }
+ if( !(arg.conversion).isNull() )
+ stream << " )";
+ }
+ stream << ";\n";
+ }
+ stream << " if( !dcopClient()->call( \"kded\", \"kdeintegration\",\"" + function.name + "(";
+ bool need_comma = false;
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.ignore )
+ continue;
+ if( need_comma )
+ stream << ",";
+ need_comma = true;
+ stream << arg.type;
+ }
+ stream << ")\", data, replyType, replyData, true ))\n";
+ stream << " {\n";
+ if( function.return_type != "void" )
+ {
+ stream << " " + function.return_type << " ret;\n";
+ stream << " dcopTypeInit( ret ); // set to false/0/whatever\n";
+ stream << " return ret;\n";
+ }
+ else
+ stream << " return;\n";
+ stream << " }\n";
+ bool return_data = false;
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ !return_data && it2 != function.args.end();
+ ++it2 )
+ {
+ if( (*it2).out_argument )
+ return_data = true;
+ }
+ if( return_data || function.return_type != "void" )
+ stream << " QDataStream replystream( replyData, IO_ReadOnly );\n";
+ if( function.return_type != "void" )
+ {
+ stream << " " + function.return_type << " ret;\n";
+ stream << " replystream >> ret;\n";
+ }
+ if( return_data )
+ {
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.out_argument && arg.needs_deref )
+ stream << " " << arg.type << " " << arg.name + "_dummy;\n";
+ }
+ stream << " replystream";
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.out_argument )
+ {
+ stream << " >> ";
+ if( !(arg.back_conversion).isNull() )
+ stream << arg.name + "_dummy";
+ else
+ {
+ if( arg.needs_deref )
+ stream << "( " << arg.name << " != NULL ? *" << arg.name << " : " << arg.name << "_dummy )";
+ else
+ stream << arg.name;
+ }
+ }
+ }
+ stream << ";\n";
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.out_argument && (!(arg.back_conversion).isNull()) )
+ stream << " if( " << arg.name << " != NULL )\n"
+ << makeIndent( 8 ) << "*" << arg.name << " = " << arg.back_conversion << "( " << arg.name + "_dummy );\n";
+ }
+ }
+ if( function.return_type != "void" )
+ stream << " return ret;\n";
+ stream << " }\n";
+ stream << "\n";
+ }
+ }
+
+void generateKdeDcop( QTextStream& stream )
+ {
+ stream <<
+"bool Module::process(const QCString &fun, const QByteArray &data,\n"
+" QCString &replyType, QByteArray &replyData)\n"
+" {\n";
+ for( QValueList< Function >::ConstIterator it1 = functions.begin();
+ it1 != functions.end();
+ ++it1 )
+ {
+ const Function& function = *it1;
+ if( function.only_qt )
+ continue;
+ stream << " if( fun == \"" + function.name + "(";
+ bool need_comma = false;
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.ignore )
+ continue;
+ if( need_comma )
+ stream << ",";
+ need_comma = true;
+ stream << arg.type;
+ }
+ stream << ")\" )\n";
+ stream << " {\n";
+ if( function.delayed_return )
+ stream << " pre_" + function.name + "( data );\n";
+ else
+ {
+ stream << " pre_" + function.name + "( data, replyData );\n";
+ stream << " replyType = \"" << function.return_type << "\";\n";
+ }
+ stream << " return true;\n";
+ stream << " }\n";
+ }
+ stream <<
+" return KDEDModule::process( fun, data, replyType, replyData );\n"
+" }\n"
+"\n";
+ stream <<
+"QCStringList Module::functions()\n"
+" {\n"
+" QCStringList funcs = KDEDModule::functions();\n";
+ for( QValueList< Function >::ConstIterator it1 = functions.begin();
+ it1 != functions.end();
+ ++it1 )
+ {
+ const Function& function = *it1;
+ if( function.only_qt )
+ continue;
+ stream << " funcs << \"" + function.name + "(";
+ bool need_comma = false;
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.ignore )
+ continue;
+ if( need_comma )
+ stream << ",";
+ need_comma = true;
+ stream << arg.type;
+ }
+ stream << ")\";\n";
+ }
+ stream <<
+" return funcs;\n"
+" }\n"
+"\n"
+"QCStringList Module::interfaces()\n"
+" {\n"
+" QCStringList ifaces = KDEDModule::interfaces();\n"
+" ifaces << \"KDEIntegration\";\n"
+" return ifaces;\n"
+" }\n"
+"\n";
+ }
+
+void generateKdePreStub( QTextStream& stream )
+ {
+ for( QValueList< Function >::ConstIterator it1 = functions.begin();
+ it1 != functions.end();
+ ++it1 )
+ {
+ const Function& function = *it1;
+ if( function.only_qt )
+ continue;
+ stream << "void Module::pre_" + function.name + "( const QByteArray& "
+ + ( function.args.isEmpty() ? "" : "data" )
+ + ( function.delayed_return ? "" : ", QByteArray& replyData" )
+ + " )\n";
+ stream << " {\n";
+ if( function.delayed_return )
+ {
+ stream << " JobData job;\n";
+ stream << " job.transaction = kapp->dcopClient()->beginTransaction();\n";
+ stream << " job.type = JobData::" + QString( function.name[ 0 ].upper()) + function.name.mid( 1 ) + ";\n";
+ }
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.ignore )
+ continue;
+ stream << " " + arg.type + " " + arg.name + ";\n";
+ }
+ if( !function.args.isEmpty())
+ {
+ stream << " QDataStream datastream( data, IO_ReadOnly );\n";
+ stream << " datastream";
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.ignore )
+ continue;
+ stream << " >> " + arg.name;
+ }
+ stream << ";\n";
+ }
+ if( function.delayed_return )
+ stream << " void* handle = " + function.name + "( ";
+ else
+ stream << " post_" + function.name + "( " + function.name + "( ";
+ bool need_comma = false;
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.ignore )
+ continue;
+ if( need_comma )
+ stream << ", ";
+ need_comma = true;
+ stream << arg.name;
+ }
+ if( function.delayed_return )
+ {
+ stream << " );\n";
+ stream << " jobs[ handle ] = job;\n";
+ }
+ else
+ stream << " ), replyData );\n";
+ stream << " }\n";
+ stream << "\n";
+ }
+ }
+
+void generateKdePostStub( QTextStream& stream )
+ {
+ for( QValueList< Function >::ConstIterator it1 = functions.begin();
+ it1 != functions.end();
+ ++it1 )
+ {
+ const Function& function = *it1;
+ if( function.only_qt )
+ continue;
+ stream << "void Module::post_" + function.name + "( ";
+ bool needs_comma = false;
+ if( function.delayed_return )
+ {
+ stream << "void* handle";
+ needs_comma = true;
+ }
+ if( function.return_type != "void" )
+ {
+ if( needs_comma )
+ stream << ", ";
+ needs_comma = true;
+ stream << function.return_type + " ret";
+ }
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.out_argument )
+ {
+ if( needs_comma )
+ stream << ", ";
+ needs_comma = true;
+ stream << arg.type + " " + arg.name;
+ }
+ }
+ if( !function.delayed_return )
+ stream << ( needs_comma ? "," : "" ) << " QByteArray& replyData";
+ stream << " )\n";
+ stream << " {\n";
+ if( function.delayed_return )
+ {
+ stream << " assert( jobs.contains( handle ));\n";
+ stream << " JobData job = jobs[ handle ];\n";
+ stream << " jobs.remove( handle );\n";
+ stream << " QByteArray replyData;\n";
+ stream << " QCString replyType = \"qtkde\";\n";
+ }
+ bool return_data = false;
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ !return_data && it2 != function.args.end();
+ ++it2 )
+ {
+ if( (*it2).out_argument )
+ return_data = true;
+ }
+ if( function.return_type != "void" || return_data )
+ stream << " QDataStream replystream( replyData, IO_WriteOnly );\n";
+ if( function.return_type != "void" )
+ stream << " replystream << ret;\n";
+ if( return_data )
+ {
+ stream << " replystream";
+ for( QValueList< Arg >::ConstIterator it2 = function.args.begin();
+ it2 != function.args.end();
+ ++it2 )
+ {
+ const Arg& arg = (*it2);
+ if( arg.out_argument )
+ stream << " << " + arg.name;
+ }
+ stream << ";\n";
+ }
+ if( function.delayed_return )
+ stream << " kapp->dcopClient()->endTransaction( job.transaction, replyType, replyData );\n";
+ stream << " }\n";
+ stream << "\n";
+ }
+ }
+
+void generateKdeStubs( QTextStream& stream )
+ {
+ generateKdePreStub( stream );
+ generateKdePostStub( stream );
+// TODO udelat i predbezne deklarace pro skutecne funkce?
+ }
+
+void generateKdeCpp()
+ {
+ QFile file( "module_functions.cpp" );
+ if( !file.open( IO_WriteOnly ))
+ error();
+ QTextStream stream( &file );
+ generateKdeDcop( stream );
+ generateKdeStubs( stream );
+ }
+
+void generateKdeH()
+ {
+ QFile file( "module_functions.h" );
+ if( !file.open( IO_WriteOnly ))
+ error();
+ QTextStream stream( &file );
+ for( QValueList< Function >::ConstIterator it1 = functions.begin();
+ it1 != functions.end();
+ ++it1 )
+ {
+ const Function& function = *it1;
+ if( function.only_qt )
+ continue;
+ Function real_function = function;
+ if( function.delayed_return )
+ real_function.return_type = "void*";
+ generateFunction( stream, real_function, real_function.name, 8,
+ false /*static*/, false /*orig type*/, true /*ignore deref*/, 2 /*ignore level*/ );
+ stream << ";\n";
+ stream << makeIndent( 8 ) + "void pre_" + function.name + "( const QByteArray& data"
+ + ( function.delayed_return ? "" : ", QByteArray& replyData" ) + " );\n";
+ Function post_function = function;
+ post_function.stripNonOutArguments();
+ if( function.return_type != "void" )
+ {
+ Arg return_arg;
+ return_arg.name = "ret";
+ return_arg.type = function.return_type;
+ post_function.args.prepend( return_arg );
+ }
+ if( function.delayed_return )
+ {
+ Arg handle_arg;
+ handle_arg.name = "handle";
+ handle_arg.type = "void*";
+ post_function.args.prepend( handle_arg );
+ }
+ else
+ {
+ Arg handle_arg;
+ handle_arg.name = "replyData";
+ handle_arg.type = "QByteArray&";
+ post_function.args.append( handle_arg );
+ }
+ post_function.return_type = "void";
+ generateFunction( stream, post_function, "post_" + post_function.name, 8,
+ false /*static*/, false /*orig type*/, true /*ignore deref*/, 2 /*ignore level*/ );
+ stream << ";\n";
+ }
+ }
+
+void generateKde()
+ {
+ generateKdeCpp();
+ generateKdeH();
+ }
+
+void generate()
+ {
+ generateQt();
+ generateQtKde();
+ generateKde();
+ }
+
+int main (int argc, char *argv[])
+ {
+ if (argc > 1) {
+ parse(TQString(argv[1]));
+ }
+ else {
+ parse(TQString("gen.txt"));
+ }
+ generate();
+ return 0;
+ }