• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • dcop
 

dcop

  • dcop
  • dcopidl2cpp
skel.cpp
1/*****************************************************************
2Copyright (c) 1999 Torben Weis <weis@kde.org>
3Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22******************************************************************/
23#include <tqdom.h>
24#include <tqfile.h>
25#include <tqtextstream.h>
26#include <tqstring.h>
27#include <tqstringlist.h>
28
29#include <string.h>
30#include <stdlib.h>
31#include <stdio.h>
32#include <unistd.h>
33#include "main.h"
34#include "type.h"
35
36static int const primes[] =
37{
38 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
39 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
40 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
41 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
42 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
43 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
44 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
45 353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
46 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
47 467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
48 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,0
49};
50
51
52struct Function
53{
54 Function(){}
55 Function( const TQString& t, const TQString& n, const TQString&fn, bool h )
56 : type( t ), name( n ), fullName( fn ), hidden( h ) {}
57 TQString type;
58 TQString name;
59 TQString fullName;
60 bool hidden;
61};
62
63
64/*
65 * Writes the skeleton
66 */
67void generateSkel( const TQString& idl, const TQString& filename, TQDomElement de )
68{
69 TQFile skel( filename );
70 if ( !skel.open( IO_WriteOnly ) )
71 tqFatal("Could not write to %s", filename.local8Bit().data() );
72
73 TQTextStream str( &skel );
74
75 str << "/****************************************************************************" << endl;
76 str << "**" << endl;
77 str << "** DCOP Skeleton generated by dcopidl2cpp from " << idl << endl;
78 str << "**" << endl;
79 str << "** WARNING! All changes made in this file will be lost!" << endl;
80 str << "**" << endl;
81 str << "*****************************************************************************/" << endl;
82 str << endl;
83
84 TQDomElement e = de.firstChild().toElement();
85 if ( e.tagName() == "SOURCE" ) {
86 str << "#include \"" << e.firstChild().toText().data() << "\"" << endl << endl;
87 }
88
89 for( ; !e.isNull(); e = e.nextSibling().toElement() ) {
90 if ( e.tagName() != "CLASS" )
91 continue;
92 TQDomElement n = e.firstChild().toElement();
93 Q_ASSERT( n.tagName() == "NAME" );
94 TQString className = n.firstChild().toText().data();
95 // find dcop parent ( rightmost super class )
96 TQString DCOPParent;
97 TQDomElement s = n.nextSibling().toElement();
98 for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
99 if ( s.tagName() == "SUPER" )
100 DCOPParent = s.firstChild().toText().data();
101 }
102
103 // get function table
104 TQValueList<Function> functions;
105 s = n.nextSibling().toElement();
106 for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
107 if ( s.tagName() != "FUNC" )
108 continue;
109 TQDomElement r = s.firstChild().toElement();
110 Q_ASSERT( r.tagName() == "TYPE" );
111 TQString funcType = r.firstChild().toText().data();
112 r = r.nextSibling().toElement();
113 Q_ASSERT ( r.tagName() == "NAME" );
114 TQString funcName = r.firstChild().toText().data();
115 TQStringList argtypes;
116 TQStringList argnames;
117 r = r.nextSibling().toElement();
118 for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
119 Q_ASSERT( r.tagName() == "ARG" );
120 TQDomElement a = r.firstChild().toElement();
121 Q_ASSERT( a.tagName() == "TYPE" );
122 argtypes.append( a.firstChild().toText().data() );
123 a = a.nextSibling().toElement();
124 if ( !a.isNull() ) {
125 Q_ASSERT( a.tagName() == "NAME" );
126 argnames.append( a.firstChild().toText().data() );
127 } else {
128 argnames.append( TQString::null );
129 }
130 }
131 funcName += '(';
132 TQString fullFuncName = funcName;
133 bool first = true;
134 TQStringList::Iterator ittype = argtypes.begin();
135 TQStringList::Iterator itname = argnames.begin();
136 while ( ittype != argtypes.end() && itname != argnames.end() ) {
137 if ( !first ) {
138 funcName += ',';
139 fullFuncName += ',';
140 }
141 first = false;
142 funcName += *ittype;
143 fullFuncName += *ittype;
144 if ( ! (*itname).isEmpty() ) {
145 fullFuncName += ' ';
146 fullFuncName += *itname;
147 }
148 ++ittype;
149 ++itname;
150 }
151 funcName += ')';
152 fullFuncName += ')';
153 bool hidden = (s.attribute("hidden") == "yes");
154 functions.append( Function( funcType, funcName, fullFuncName, hidden ) );
155 }
156
157 // create static tables
158
159 int fhash = functions.count() + 1;
160 for ( int i = 0; primes[i]; i++ ) {
161 if ( primes[i] > static_cast<int>(functions.count()) ) {
162 fhash = primes[i];
163 break;
164 }
165 }
166
167 str << "#include <kdatastream.h>" << endl;
168
169 bool useHashing = functions.count() > 7;
170 if ( useHashing ) {
171 str << "#include <tqasciidict.h>" << endl;
172 }
173
174 TQString classNameFull = className; // class name with possible namespaces prepended
175 // namespaces will be removed from className now
176 int namespace_count = 0;
177 TQString namespace_tmp = className;
178 str << endl;
179 for(;;) {
180 int pos = namespace_tmp.find( "::" );
181 if( pos < 0 ) {
182 className = namespace_tmp;
183 break;
184 }
185 str << "namespace " << namespace_tmp.left( pos ) << " {" << endl;
186 ++namespace_count;
187 namespace_tmp = namespace_tmp.mid( pos + 2 );
188 }
189
190 str << endl;
191
192 if ( useHashing ) {
193 str << "static const int " << className << "_fhash = " << fhash << ";" << endl;
194 }
195 str << "static const char* const " << className << "_ftable[" << functions.count() + 1 << "][3] = {" << endl;
196 for( TQValueList<Function>::Iterator it = functions.begin(); it != functions.end(); ++it ){
197 str << " { \"" << (*it).type << "\", \"" << (*it).name << "\", \"" << (*it).fullName << "\" }," << endl;
198 }
199 str << " { 0, 0, 0 }" << endl;
200 str << "};" << endl;
201
202 if (functions.count() > 0) {
203 str << "static const int " << className << "_ftable_hiddens[" << functions.count() << "] = {" << endl;
204 for( TQValueList<Function>::Iterator it = functions.begin(); it != functions.end(); ++it ){
205 str << " " << !!(*it).hidden << "," << endl;
206 }
207 str << "};" << endl;
208 }
209
210 str << endl;
211
212
213 // Write dispatcher
214 str << "bool " << className;
215 str << "::process(const TQCString &fun, const TQByteArray &data, TQCString& replyType, TQByteArray &replyData)" << endl;
216 str << "{" << endl;
217 if ( useHashing ) {
218 str << " static TQAsciiDict<int>* fdict = 0;" << endl;
219
220 str << " if ( !fdict ) {" << endl;
221 str << "\tfdict = new TQAsciiDict<int>( " << className << "_fhash, true, false );" << endl;
222 str << "\tfor ( int i = 0; " << className << "_ftable[i][1]; i++ )" << endl;
223 str << "\t fdict->insert( " << className << "_ftable[i][1], new int( i ) );" << endl;
224 str << " }" << endl;
225
226 str << " int* fp = fdict->find( fun );" << endl;
227 str << " switch ( fp?*fp:-1) {" << endl;
228 }
229 s = n.nextSibling().toElement();
230 int fcount = 0; // counter of written functions
231 bool firstFunc = true;
232 for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
233 if ( s.tagName() != "FUNC" )
234 continue;
235 TQDomElement r = s.firstChild().toElement();
236 Q_ASSERT( r.tagName() == "TYPE" );
237 TQString funcType = r.firstChild().toText().data();
238 if ( funcType == "ASYNC" )
239 funcType = "void";
240 r = r.nextSibling().toElement();
241 Q_ASSERT ( r.tagName() == "NAME" );
242 TQString funcName = r.firstChild().toText().data();
243 TQStringList args;
244 TQStringList argtypes;
245 r = r.nextSibling().toElement();
246 for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
247 Q_ASSERT( r.tagName() == "ARG" );
248 TQDomElement a = r.firstChild().toElement();
249 Q_ASSERT( a.tagName() == "TYPE" );
250 argtypes.append( a.firstChild().toText().data() );
251 args.append( TQString("arg" ) + TQString::number( args.count() ) );
252 }
253 TQString plainFuncName = funcName;
254 funcName += '(';
255 bool first = true;
256 for( TQStringList::Iterator argtypes_count = argtypes.begin(); argtypes_count != argtypes.end(); ++argtypes_count ){
257 if ( !first )
258 funcName += ',';
259 first = false;
260 funcName += *argtypes_count;
261 }
262 funcName += ')';
263
264 if ( useHashing ) {
265 str << " case " << fcount << ": { // " << funcType << " " << funcName << endl;
266 } else {
267 if ( firstFunc )
268 str << " if ( fun == " << className << "_ftable[" << fcount << "][1] ) { // " << funcType << " " << funcName << endl;
269 else
270 str << " else if ( fun == " << className << "_ftable[" << fcount << "][1] ) { // " << funcType << " " << funcName << endl;
271 firstFunc = false;
272 }
273 if ( !args.isEmpty() ) {
274 TQStringList::Iterator ittypes = argtypes.begin();
275 TQStringList::Iterator args_count;
276 for( args_count = args.begin(); args_count != args.end(); ++args_count ){
277 str << '\t'<< *ittypes << " " << *args_count << ";" << endl;
278 ++ittypes;
279 }
280 str << "\tTQDataStream arg( data, IO_ReadOnly );" << endl;
281 for( args_count = args.begin(); args_count != args.end(); ++args_count ){
282 str << "\tif (arg.atEnd()) return false;" << endl; // Basic error checking
283 str << "\targ >> " << *args_count << ";" << endl;
284 }
285 }
286
287 str << "\treplyType = " << className << "_ftable[" << fcount++ << "][0]; " << endl;
288 if ( funcType == "void" ) {
289 str << '\t' << plainFuncName << '(';
290 } else {
291 str << "\tTQDataStream _replyStream( replyData, IO_WriteOnly );" << endl;
292 str << "\t_replyStream << " << plainFuncName << '(';
293 }
294
295 first = true;
296 for ( TQStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){
297 if ( !first )
298 str << ", ";
299 first = false;
300 str << *args_count;
301 }
302 str << " );" << endl;
303 if (useHashing ) {
304 str << " } break;" << endl;
305 } else {
306 str << " }";
307 }
308 }
309
310 // only open an 'else' clause if there were one or more functions
311 if ( fcount > 0 ) {
312 if ( useHashing ) {
313 str << " default: " << endl;
314 } else {
315 str << " else {" << endl;
316 }
317 }
318
319 // if no DCOP function was called, delegate the request to the parent
320 if (!DCOPParent.isEmpty()) {
321 str << "\treturn " << DCOPParent << "::process( fun, data, replyType, replyData );" << endl;
322 } else {
323 str << "\treturn false;" << endl;
324 }
325
326 // only close the 'else' clause and add the default 'return true'
327 // (signifying a DCOP method was found and called) if there were
328 // one or more functions.
329 if ( fcount > 0 ) {
330 str << " }" << endl;
331 str << " return true;" << endl;
332 }
333
334 // close the 'process' function
335 str << "}" << endl << endl;
336
337 str << "QCStringList " << className;
338 str << "::interfaces()" << endl;
339 str << "{" << endl;
340 if (!DCOPParent.isEmpty()) {
341 str << " QCStringList ifaces = " << DCOPParent << "::interfaces();" << endl;
342 } else {
343 str << " QCStringList ifaces;" << endl;
344 }
345 str << " ifaces += \"" << classNameFull << "\";" << endl;
346 str << " return ifaces;" << endl;
347 str << "}" << endl << endl;
348
349
350 str << "QCStringList " << className;
351 str << "::functions()" << endl;
352 str << "{" << endl;
353 if (!DCOPParent.isEmpty()) {
354 str << " QCStringList funcs = " << DCOPParent << "::functions();" << endl;
355 } else {
356 str << " QCStringList funcs;" << endl;
357 }
358 str << " for ( int i = 0; " << className << "_ftable[i][2]; i++ ) {" << endl;
359 if (functions.count() > 0) {
360 str << "\tif (" << className << "_ftable_hiddens[i])" << endl;
361 str << "\t continue;" << endl;
362 }
363 str << "\tTQCString func = " << className << "_ftable[i][0];" << endl;
364 str << "\tfunc += ' ';" << endl;
365 str << "\tfunc += " << className << "_ftable[i][2];" << endl;
366 str << "\tfuncs << func;" << endl;
367 str << " }" << endl;
368 str << " return funcs;" << endl;
369 str << "}" << endl << endl;
370
371 // Add signal stubs
372 for(s = e.firstChild().toElement(); !s.isNull(); s = s.nextSibling().toElement() ) {
373 if (s.tagName() != "SIGNAL")
374 continue;
375 TQDomElement r = s.firstChild().toElement();
376 TQString result = writeType( str, r );
377
378 r = r.nextSibling().toElement();
379 Q_ASSERT ( r.tagName() == "NAME" );
380 TQString funcName = r.firstChild().toText().data();
381 str << className << "::" << funcName << "(";
382
383 TQStringList args;
384 TQStringList argtypes;
385 bool first = true;
386 r = r.nextSibling().toElement();
387 for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
388 if ( !first )
389 str << ", ";
390 else
391 str << " ";
392 first = false;
393 Q_ASSERT( r.tagName() == "ARG" );
394 TQDomElement a = r.firstChild().toElement();
395 TQString type = writeType( str, a );
396 argtypes.append( type );
397 args.append( TQString("arg" ) + TQString::number( args.count() ) ) ;
398 str << args.last();
399 }
400 if ( !first )
401 str << " ";
402 str << ")";
403
404 if ( s.hasAttribute("qual") )
405 str << " " << s.attribute("qual");
406 str << endl;
407
408 str << "{" << endl ;
409
410 funcName += "(";
411 first = true;
412 for( TQStringList::Iterator it = argtypes.begin(); it != argtypes.end(); ++it ){
413 if ( !first )
414 funcName += ",";
415 first = false;
416 funcName += *it;
417 }
418 funcName += ")";
419
420 if ( result != "void" )
421 tqFatal("Error in DCOP signal %s::%s: DCOP signals can not return values.", className.latin1(), funcName.latin1());
422
423 str << " TQByteArray data;" << endl;
424 if ( !args.isEmpty() ) {
425 str << " TQDataStream arg( data, IO_WriteOnly );" << endl;
426 for( TQStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){
427 str << " arg << " << *args_count << ";" << endl;
428 }
429 }
430
431 str << " emitDCOPSignal( \"" << funcName << "\", data );" << endl;
432
433 str << "}" << endl << endl;
434
435 }
436
437 for(; namespace_count > 0; --namespace_count )
438 str << "} // namespace" << endl;
439 str << endl;
440 }
441
442 skel.close();
443}
444
445// :set expandtab!<RETURN>:set ts=8<RETURN>:set sts=4<RETURN>:set sw=4<RETURN>
endl
kndbgstream & endl(kndbgstream &s)
TDEStdAccel::name
TQString name(StdAccel id)

dcop

Skip menu "dcop"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

dcop

Skip menu "dcop"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for dcop by doxygen 1.9.4
This website is maintained by Timothy Pearson.