00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include <qdom.h>
00024
#include <qfile.h>
00025
#include <qtextstream.h>
00026
#include <qstring.h>
00027
#include <qstringlist.h>
00028
00029
#include <string.h>
00030
#include <stdlib.h>
00031
#include <stdio.h>
00032
#include <unistd.h>
00033
#include "main.h"
00034
#include "type.h"
00035
00036
static int const primes[] =
00037 {
00038 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
00039 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
00040 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
00041 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
00042 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
00043 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
00044 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
00045 353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
00046 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
00047 467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
00048 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,0
00049 };
00050
00051
00052
struct Function
00053 {
00054 Function(){};
00055 Function(
const QString& t,
const QString& n,
const QString&fn,
bool h )
00056 : type( t ),
name( n ), fullName( fn ), hidden( h ) {}
00057
QString type;
00058
QString name;
00059
QString fullName;
00060
bool hidden;
00061 };
00062
00063
00064
00065
00066
00067
void generateSkel(
const QString& idl,
const QString& filename,
QDomElement de )
00068 {
00069
QFile skel( filename );
00070
if ( !skel.
open( IO_WriteOnly ) )
00071 qFatal(
"Could not write to %s", filename.
local8Bit().data() );
00072
00073
QTextStream str( &skel );
00074
00075 str <<
"/****************************************************************************" <<
endl;
00076 str <<
"**" <<
endl;
00077 str <<
"** DCOP Skeleton created by dcopidl2cpp from " << idl <<
endl;
00078 str <<
"**" <<
endl;
00079 str <<
"** WARNING! All changes made in this file will be lost!" <<
endl;
00080 str <<
"**" <<
endl;
00081 str <<
"*****************************************************************************/" <<
endl;
00082 str <<
endl;
00083
00084
QDomElement e = de.firstChild().toElement();
00085
if ( e.
tagName() ==
"SOURCE" ) {
00086 str <<
"#include \"" << e.firstChild().toText().data() <<
"\"" <<
endl <<
endl;
00087 }
00088
00089
for( ; !e.isNull(); e = e.nextSibling().toElement() ) {
00090
if ( e.
tagName() !=
"CLASS" )
00091
continue;
00092
QDomElement n = e.firstChild().toElement();
00093 Q_ASSERT( n.
tagName() ==
"NAME" );
00094
QString className = n.firstChild().toText().data();
00095
00096
QString DCOPParent;
00097
QDomElement s = n.nextSibling().toElement();
00098
for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
00099
if ( s.
tagName() ==
"SUPER" )
00100 DCOPParent = s.firstChild().toText().data();
00101 }
00102
00103
00104
QValueList<Function> functions;
00105 s = n.nextSibling().toElement();
00106
for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
00107
if ( s.
tagName() !=
"FUNC" )
00108
continue;
00109
QDomElement r = s.firstChild().toElement();
00110 Q_ASSERT( r.
tagName() ==
"TYPE" );
00111
QString funcType = r.firstChild().toText().data();
00112 r = r.nextSibling().toElement();
00113 Q_ASSERT ( r.
tagName() ==
"NAME" );
00114
QString funcName = r.firstChild().toText().data();
00115
QStringList argtypes;
00116
QStringList argnames;
00117 r = r.nextSibling().toElement();
00118
for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
00119 Q_ASSERT( r.
tagName() ==
"ARG" );
00120
QDomElement a = r.firstChild().toElement();
00121 Q_ASSERT( a.
tagName() ==
"TYPE" );
00122 argtypes.append( a.firstChild().toText().data() );
00123 a = a.nextSibling().toElement();
00124
if ( !a.isNull() ) {
00125 Q_ASSERT( a.
tagName() ==
"NAME" );
00126 argnames.append( a.firstChild().toText().data() );
00127 }
else {
00128 argnames.append( QString::null );
00129 }
00130 }
00131 funcName +=
'(';
00132
QString fullFuncName = funcName;
00133
bool first =
true;
00134 QStringList::Iterator ittype = argtypes.begin();
00135 QStringList::Iterator itname = argnames.begin();
00136
while ( ittype != argtypes.end() && itname != argnames.end() ) {
00137
if ( !first ) {
00138 funcName +=
',';
00139 fullFuncName +=
',';
00140 }
00141 first =
false;
00142 funcName += *ittype;
00143 fullFuncName += *ittype;
00144
if ( ! (*itname).isEmpty() ) {
00145 fullFuncName +=
' ';
00146 fullFuncName += *itname;
00147 }
00148 ++ittype;
00149 ++itname;
00150 }
00151 funcName +=
')';
00152 fullFuncName +=
')';
00153
bool hidden = (s.
attribute(
"hidden") ==
"yes");
00154 functions.
append( Function( funcType, funcName, fullFuncName, hidden ) );
00155 }
00156
00157
00158
00159
int fhash = functions.
count() + 1;
00160
for (
int i = 0; primes[i]; i++ ) {
00161
if ( primes[i] > static_cast<int>(functions.
count()) ) {
00162 fhash = primes[i];
00163
break;
00164 }
00165 }
00166
00167 str <<
"#include <kdatastream.h>" <<
endl;
00168
00169
bool useHashing = functions.
count() > 7;
00170
if ( useHashing ) {
00171 str <<
"#include <qasciidict.h>" <<
endl;
00172 }
00173
00174
QString classNameFull = className;
00175
00176
int namespace_count = 0;
00177
QString namespace_tmp = className;
00178 str <<
endl;
00179
for(;;) {
00180
int pos = namespace_tmp.
find(
"::" );
00181
if( pos < 0 ) {
00182 className = namespace_tmp;
00183
break;
00184 }
00185 str <<
"namespace " << namespace_tmp.
left( pos ) <<
" {" <<
endl;
00186 ++namespace_count;
00187 namespace_tmp = namespace_tmp.
mid( pos + 2 );
00188 }
00189
00190 str <<
endl;
00191
00192
if ( useHashing ) {
00193 str <<
"static const int " << className <<
"_fhash = " << fhash <<
";" <<
endl;
00194 }
00195 str <<
"static const char* const " << className <<
"_ftable[" << functions.
count() + 1 <<
"][3] = {" <<
endl;
00196
for(
QValueList<Function>::Iterator it = functions.
begin(); it != functions.
end(); ++it ){
00197 str <<
" { \"" << (*it).type <<
"\", \"" << (*it).name <<
"\", \"" << (*it).fullName <<
"\" }," <<
endl;
00198 }
00199 str <<
" { 0, 0, 0 }" <<
endl;
00200 str <<
"};" <<
endl;
00201
00202
if (functions.
count() > 0) {
00203 str <<
"static const int " << className <<
"_ftable_hiddens[" << functions.
count() <<
"] = {" <<
endl;
00204
for(
QValueList<Function>::Iterator it = functions.
begin(); it != functions.
end(); ++it ){
00205 str <<
" " << !!(*it).hidden <<
"," <<
endl;
00206 }
00207 str <<
"};" <<
endl;
00208 }
00209
00210 str <<
endl;
00211
00212
00213
00214 str <<
"bool " << className;
00215 str <<
"::process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &replyData)" <<
endl;
00216 str <<
"{" <<
endl;
00217
if ( useHashing ) {
00218 str <<
" static QAsciiDict<int>* fdict = 0;" <<
endl;
00219
00220 str <<
" if ( !fdict ) {" <<
endl;
00221 str <<
"\tfdict = new QAsciiDict<int>( " << className <<
"_fhash, true, false );" <<
endl;
00222 str <<
"\tfor ( int i = 0; " << className <<
"_ftable[i][1]; i++ )" <<
endl;
00223 str <<
"\t fdict->insert( " << className <<
"_ftable[i][1], new int( i ) );" <<
endl;
00224 str <<
" }" <<
endl;
00225
00226 str <<
" int* fp = fdict->find( fun );" <<
endl;
00227 str <<
" switch ( fp?*fp:-1) {" <<
endl;
00228 }
00229 s = n.nextSibling().toElement();
00230
int fcount = 0;
00231
bool firstFunc =
true;
00232
for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
00233
if ( s.
tagName() !=
"FUNC" )
00234
continue;
00235
QDomElement r = s.firstChild().toElement();
00236 Q_ASSERT( r.
tagName() ==
"TYPE" );
00237
QString funcType = r.firstChild().toText().data();
00238
if ( funcType ==
"ASYNC" )
00239 funcType =
"void";
00240 r = r.nextSibling().toElement();
00241 Q_ASSERT ( r.
tagName() ==
"NAME" );
00242
QString funcName = r.firstChild().toText().data();
00243
QStringList args;
00244
QStringList argtypes;
00245 r = r.nextSibling().toElement();
00246
for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
00247 Q_ASSERT( r.
tagName() ==
"ARG" );
00248
QDomElement a = r.firstChild().toElement();
00249 Q_ASSERT( a.
tagName() ==
"TYPE" );
00250 argtypes.append( a.firstChild().toText().data() );
00251 args.append(
QString(
"arg" ) + QString::number( args.count() ) );
00252 }
00253
QString plainFuncName = funcName;
00254 funcName +=
'(';
00255
bool first =
true;
00256
for( QStringList::Iterator argtypes_count = argtypes.begin(); argtypes_count != argtypes.end(); ++argtypes_count ){
00257
if ( !first )
00258 funcName +=
',';
00259 first =
false;
00260 funcName += *argtypes_count;
00261 }
00262 funcName +=
')';
00263
00264
if ( useHashing ) {
00265 str <<
" case " << fcount <<
": { // " << funcType <<
" " << funcName <<
endl;
00266 }
else {
00267
if ( firstFunc )
00268 str <<
" if ( fun == " << className <<
"_ftable[" << fcount <<
"][1] ) { // " << funcType <<
" " << funcName <<
endl;
00269
else
00270 str <<
" else if ( fun == " << className <<
"_ftable[" << fcount <<
"][1] ) { // " << funcType <<
" " << funcName <<
endl;
00271 firstFunc =
false;
00272 }
00273
if ( !args.isEmpty() ) {
00274 QStringList::Iterator ittypes = argtypes.begin();
00275 QStringList::Iterator args_count;
00276
for( args_count = args.begin(); args_count != args.end(); ++args_count ){
00277 str <<
'\t'<< *ittypes <<
" " << *args_count <<
";" <<
endl;
00278 ++ittypes;
00279 }
00280 str <<
"\tQDataStream arg( data, IO_ReadOnly );" <<
endl;
00281
for( args_count = args.begin(); args_count != args.end(); ++args_count ){
00282 str <<
"\targ >> " << *args_count <<
";" <<
endl;
00283 }
00284 }
00285
00286 str <<
"\treplyType = " << className <<
"_ftable[" << fcount++ <<
"][0]; " <<
endl;
00287
if ( funcType ==
"void" ) {
00288 str <<
'\t' << plainFuncName <<
'(';
00289 }
else {
00290 str <<
"\tQDataStream _replyStream( replyData, IO_WriteOnly );" <<
endl;
00291 str <<
"\t_replyStream << " << plainFuncName <<
'(';
00292 }
00293
00294 first =
true;
00295
for ( QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){
00296
if ( !first )
00297 str <<
", ";
00298 first =
false;
00299 str << *args_count;
00300 }
00301 str <<
" );" <<
endl;
00302
if (useHashing ) {
00303 str <<
" } break;" <<
endl;
00304 }
else {
00305 str <<
" }";
00306 }
00307 }
00308
00309
00310
if ( fcount > 0 ) {
00311
if ( useHashing ) {
00312 str <<
" default: " <<
endl;
00313 }
else {
00314 str <<
" else {" <<
endl;
00315 }
00316 }
00317
00318
00319
if (!DCOPParent.
isEmpty()) {
00320 str <<
"\treturn " << DCOPParent <<
"::process( fun, data, replyType, replyData );" <<
endl;
00321 }
else {
00322 str <<
"\treturn false;" <<
endl;
00323 }
00324
00325
00326
00327
00328
if ( fcount > 0 ) {
00329 str <<
" }" <<
endl;
00330 str <<
" return true;" <<
endl;
00331 }
00332
00333
00334 str <<
"}" <<
endl <<
endl;
00335
00336 str <<
"QCStringList " << className;
00337 str <<
"::interfaces()" <<
endl;
00338 str <<
"{" <<
endl;
00339
if (!DCOPParent.
isEmpty()) {
00340 str <<
" QCStringList ifaces = " << DCOPParent <<
"::interfaces();" <<
endl;
00341 }
else {
00342 str <<
" QCStringList ifaces;" <<
endl;
00343 }
00344 str <<
" ifaces += \"" << classNameFull <<
"\";" <<
endl;
00345 str <<
" return ifaces;" <<
endl;
00346 str <<
"}" <<
endl <<
endl;
00347
00348
00349 str <<
"QCStringList " << className;
00350 str <<
"::functions()" <<
endl;
00351 str <<
"{" <<
endl;
00352
if (!DCOPParent.
isEmpty()) {
00353 str <<
" QCStringList funcs = " << DCOPParent <<
"::functions();" <<
endl;
00354 }
else {
00355 str <<
" QCStringList funcs;" <<
endl;
00356 }
00357 str <<
" for ( int i = 0; " << className <<
"_ftable[i][2]; i++ ) {" <<
endl;
00358
if (functions.
count() > 0) {
00359 str <<
"\tif (" << className <<
"_ftable_hiddens[i])" <<
endl;
00360 str <<
"\t continue;" <<
endl;
00361 }
00362 str <<
"\tQCString func = " << className <<
"_ftable[i][0];" <<
endl;
00363 str <<
"\tfunc += ' ';" <<
endl;
00364 str <<
"\tfunc += " << className <<
"_ftable[i][2];" <<
endl;
00365 str <<
"\tfuncs << func;" <<
endl;
00366 str <<
" }" <<
endl;
00367 str <<
" return funcs;" <<
endl;
00368 str <<
"}" <<
endl <<
endl;
00369
00370
00371
for(s = e.firstChild().toElement(); !s.isNull(); s = s.nextSibling().toElement() ) {
00372
if (s.
tagName() !=
"SIGNAL")
00373
continue;
00374
QDomElement r = s.firstChild().toElement();
00375
QString result = writeType( str, r );
00376
00377 r = r.nextSibling().toElement();
00378 Q_ASSERT ( r.
tagName() ==
"NAME" );
00379
QString funcName = r.firstChild().toText().data();
00380 str << className <<
"::" << funcName <<
"(";
00381
00382
QStringList args;
00383
QStringList argtypes;
00384
bool first =
true;
00385 r = r.nextSibling().toElement();
00386
for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
00387
if ( !first )
00388 str <<
", ";
00389
else
00390 str <<
" ";
00391 first =
false;
00392 Q_ASSERT( r.
tagName() ==
"ARG" );
00393
QDomElement a = r.firstChild().toElement();
00394
QString type = writeType( str, a );
00395 argtypes.append( type );
00396 args.append(
QString(
"arg" ) + QString::number( args.count() ) ) ;
00397 str << args.last();
00398 }
00399
if ( !first )
00400 str <<
" ";
00401 str <<
")";
00402
00403
if ( s.
hasAttribute(
"qual") )
00404 str <<
" " << s.
attribute(
"qual");
00405 str <<
endl;
00406
00407 str <<
"{" <<
endl ;
00408
00409 funcName +=
"(";
00410 first =
true;
00411
for( QStringList::Iterator it = argtypes.begin(); it != argtypes.end(); ++it ){
00412
if ( !first )
00413 funcName +=
",";
00414 first =
false;
00415 funcName += *it;
00416 }
00417 funcName +=
")";
00418
00419
if ( result !=
"void" )
00420 qFatal(
"Error in DCOP signal %s::%s: DCOP signals can not return values.", className.latin1(), funcName.latin1());
00421
00422 str <<
" QByteArray data;" <<
endl;
00423
if ( !args.isEmpty() ) {
00424 str <<
" QDataStream arg( data, IO_WriteOnly );" <<
endl;
00425
for( QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){
00426 str <<
" arg << " << *args_count <<
";" <<
endl;
00427 }
00428 }
00429
00430 str <<
" emitDCOPSignal( \"" << funcName <<
"\", data );" <<
endl;
00431
00432 str <<
"}" <<
endl <<
endl;
00433
00434 }
00435
00436
for(; namespace_count > 0; --namespace_count )
00437 str <<
"} // namespace" <<
endl;
00438 str <<
endl;
00439 }
00440
00441 skel.
close();
00442 }
00443
00444