summaryrefslogtreecommitdiffstats
path: root/kompare/tests/cvsdiff
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitbd9e6617827818fd043452c08c606f07b78014a0 (patch)
tree425bb4c3168f9c02f10150f235d2cb998dcc6108 /kompare/tests/cvsdiff
downloadtdesdk-bd9e6617827818fd043452c08c606f07b78014a0.tar.gz
tdesdk-bd9e6617827818fd043452c08c606f07b78014a0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdesdk@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kompare/tests/cvsdiff')
-rw-r--r--kompare/tests/cvsdiff/context.diff83
-rw-r--r--kompare/tests/cvsdiff/contextm.diff1046
-rw-r--r--kompare/tests/cvsdiff/ed.diff24
-rw-r--r--kompare/tests/cvsdiff/edm.diff692
-rw-r--r--kompare/tests/cvsdiff/normal.diff29
-rw-r--r--kompare/tests/cvsdiff/normalm.diff861
-rw-r--r--kompare/tests/cvsdiff/rcs.diff24
-rw-r--r--kompare/tests/cvsdiff/rcsm.diff683
-rw-r--r--kompare/tests/cvsdiff/unified.diff50
-rw-r--r--kompare/tests/cvsdiff/unifiedm.diff924
10 files changed, 4416 insertions, 0 deletions
diff --git a/kompare/tests/cvsdiff/context.diff b/kompare/tests/cvsdiff/context.diff
new file mode 100644
index 00000000..c9a7f855
--- /dev/null
+++ b/kompare/tests/cvsdiff/context.diff
@@ -0,0 +1,83 @@
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -c -r1.2 dcopfind.cpp
+*** client/dcopfind.cpp 2001/10/31 01:17:39 1.2
+--- client/dcopfind.cpp 2002/01/16 18:07:13
+***************
+*** 36,42 ****
+ static bool bAppIdOnly = 0;
+ static bool bLaunchApp = 0;
+
+! bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
+ {
+ QString f = func; // Qt is better with unicode strings, so use one.
+ int left = f.find( '(' );
+--- 36,42 ----
+ static bool bAppIdOnly = 0;
+ static bool bLaunchApp = 0;
+
+! bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+ {
+ QString f = func; // Qt is better with unicode strings, so use one.
+ int left = f.find( '(' );
+***************
+*** 118,124 ****
+ f = fc;
+ }
+
+! if ( (int) types.count() != argc ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+--- 118,124 ----
+ f = fc;
+ }
+
+! if ( types.count() != args.count() ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+***************
+*** 128,136 ****
+
+ int i = 0;
+ for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
+! marshall(arg, argc, args, i, *it);
+ }
+! if ( (int) i != argc ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+--- 128,136 ----
+
+ int i = 0;
+ for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
+! marshall(arg, args, i, *it);
+ }
+! if ( (uint) i != args.count() ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+***************
+*** 221,227 ****
+ argc = 0;
+ }
+
+! findObject( app, objid, function, argc, args );
+
+ return 0;
+ }
+--- 221,231 ----
+ argc = 0;
+ }
+
+! QCStringList params;
+! for( int i = 0; i < argc; i++ )
+! params.append( args[ i ] );
+!
+! findObject( app, objid, function, params );
+
+ return 0;
+ }
diff --git a/kompare/tests/cvsdiff/contextm.diff b/kompare/tests/cvsdiff/contextm.diff
new file mode 100644
index 00000000..ef20ec4c
--- /dev/null
+++ b/kompare/tests/cvsdiff/contextm.diff
@@ -0,0 +1,1046 @@
+Index: client/dcop.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcop.cpp,v
+retrieving revision 1.26
+diff -c -r1.26 dcop.cpp
+*** client/dcop.cpp 2001/10/31 01:17:39 1.26
+--- client/dcop.cpp 2002/01/16 18:06:24
+***************
+*** 20,38 ****
+
+ ******************************************************************/
+
+! #include <qvariant.h>
+ #include <qcolor.h>
+! #include "../kdatastream.h"
+ #include "../dcopclient.h"
+ #include "../dcopref.h"
+! #include <stdlib.h>
+! #include <stdio.h>
+! #include <ctype.h>
+
+ #include "marshall.cpp"
+
+ static DCOPClient* dcop = 0;
+
+ bool startsWith(const QCString &id, const char *str, int n)
+ {
+ return !n || (strncmp(id.data(), str, n) == 0);
+--- 20,66 ----
+
+ ******************************************************************/
+
+! #include <ctype.h>
+! #include <stdio.h>
+! #include <stdlib.h>
+!
+ #include <qcolor.h>
+! #include <qdir.h>
+! #include <qfile.h>
+! #include <qfileinfo.h>
+! #include <qmap.h>
+! #include <qstringlist.h>
+! #include <qtextstream.h>
+! #include <qvariant.h>
+!
+! // putenv() is not available on all platforms, so make sure the emulation
+! // wrapper is available in those cases by loading config.h!
+! #include <config.h>
+!
+ #include "../dcopclient.h"
+ #include "../dcopref.h"
+! #include "../kdatastream.h"
+
+ #include "marshall.cpp"
+
++ typedef QMap<QString, QString> UserList;
++
+ static DCOPClient* dcop = 0;
+
++ static QTextStream cout( stdout, IO_WriteOnly );
++ static QTextStream cerr( stderr, IO_WriteOnly );
++
++ /**
++ * Session to send call to
++ * DefaultSession - current session. Current KDE session when called without
++ * --user or --all-users option. Otherwise this value ignores
++ * all users with more than one active session.
++ * AllSessions - Send to all sessions found. requires --user or --all-users.
++ * QuerySessions - Don't call DCOP, return a list of available sessions.
++ * CustomSession - Use the specified session
++ */
++ enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
++
+ bool startsWith(const QCString &id, const char *str, int n)
+ {
+ return !n || (strncmp(id.data(), str, n) == 0);
+***************
+*** 118,126 ****
+ }
+ }
+
+! void callFunction( const char* app, const char* obj, const char* func, int argc, char** args )
+ {
+-
+ QString f = func; // Qt is better with unicode strings, so use one.
+ int left = f.find( '(' );
+ int right = f.find( ')' );
+--- 146,153 ----
+ }
+ }
+
+! void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
+ {
+ QString f = func; // Qt is better with unicode strings, so use one.
+ int left = f.find( '(' );
+ int right = f.find( ')' );
+***************
+*** 136,142 ****
+ bool ok = false;
+ QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
+ QCString realfunc;
+! if ( !ok && argc == 0 )
+ goto doit;
+ if ( !ok )
+ {
+--- 163,169 ----
+ bool ok = false;
+ QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
+ QCString realfunc;
+! if ( !ok && args.isEmpty() )
+ goto doit;
+ if ( !ok )
+ {
+***************
+*** 153,167 ****
+
+ if ( l > 0 && (*it).mid( s, l - s ) == func ) {
+ realfunc = (*it).mid( s );
+! int a = (*it).contains(',');
+! if ( ( a == 0 && argc == 0) || ( a > 0 && a + 1 == argc ) )
+ break;
+ }
+ }
+ if ( realfunc.isEmpty() )
+ {
+ qWarning("no such function");
+! exit(1);
+ }
+ f = realfunc;
+ left = f.find( '(' );
+--- 180,195 ----
+
+ if ( l > 0 && (*it).mid( s, l - s ) == func ) {
+ realfunc = (*it).mid( s );
+! uint a = (*it).contains(',');
+! if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
+ break;
+ }
+ }
+ if ( realfunc.isEmpty() )
+ {
+ qWarning("no such function");
+! // exit(1);
+! return;
+ }
+ f = realfunc;
+ left = f.find( '(' );
+***************
+*** 243,253 ****
+ QCString replyType;
+ QDataStream arg(data, IO_WriteOnly);
+
+! int i = 0;
+! for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
+! marshall(arg, argc, args, i, *it);
+! }
+! if ( i != argc ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+--- 271,282 ----
+ QCString replyType;
+ QDataStream arg(data, IO_WriteOnly);
+
+! uint i = 0;
+! for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
+! marshall( arg, args, i, *it );
+!
+! if ( i != args.count() )
+! {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+***************
+*** 265,343 ****
+ }
+ }
+ }
+-
+
+
+! int main( int argc, char** argv )
+ {
+
+! if ( argc > 1 && argv[1][0] == '-' ) {
+! fprintf( stderr, "Usage: dcop [ application [object [function [arg1] [arg2] [arg3] ... ] ] ] \n" );
+! exit(0);
+ }
+
+! DCOPClient client;
+! client.attach();
+! dcop = &client;
+
+ QCString app;
+ QCString objid;
+ QCString function;
+! char **args = 0;
+! if ((argc > 1) && (strncmp(argv[1], "DCOPRef(", 8)) == 0)
+ {
+! char *delim = strchr(argv[1], ',');
+! if (!delim)
+! {
+! fprintf(stderr, "Error: '%s' is not a valid DCOP reference.\n", argv[1]);
+! return 1;
+! }
+! *delim = 0;
+! app = argv[1] + 8;
+! delim++;
+! delim[strlen(delim)-1] = 0;
+! objid = delim;
+! if (argc > 2)
+! function = argv[2];
+! if (argc > 3)
+! args = &argv[3];
+! argc++;
+ }
+ else
+ {
+! if (argc > 1)
+! app = argv[1];
+! if (argc > 2)
+! objid = argv[2];
+! if (argc > 3)
+! function = argv[3];
+! if (argc > 4)
+! args = &argv[4];
+! }
+!
+! switch ( argc ) {
+! case 0:
+! case 1:
+! queryApplications("");
+! break;
+! case 2:
+! if (endsWith(app, '*'))
+! queryApplications(app);
+! else
+! queryObjects( app, "" );
+! break;
+! case 3:
+! if (endsWith(objid, '*'))
+! queryObjects(app, objid);
+! else
+! queryFunctions( app, objid );
+! break;
+! case 4:
+! default:
+! callFunction( app, objid, function, argc - 4, args );
+! break;
+
+ }
+
+ return 0;
+ }
+--- 294,773 ----
+ }
+ }
+ }
+
++ /**
++ * Show command-line help and exit
++ */
++ void showHelp( int exitCode = 0 )
++ {
++ cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
++ << "" << endl
++ << "Console DCOP client" << endl
++ << "" << endl
++ << "Generic options:" << endl
++ << " --help Show help about options" << endl
++ << "" << endl
++ << "Options:" << endl
++ << " --pipe Call DCOP for each line read from stdin" << endl
++ << " --user <user> Connect to the given user's DCOP server. This option will" << endl
++ << " ignore the values of the environment vars $DCOPSERVER and" << endl
++ << " $ICEAUTHORITY, even if they are set." << endl
++ << " If the user has more than one open session, you must also" << endl
++ << " use one of the --list-sessions, --session or --als-sessions" << endl
++ << " command-line options." << endl
++ << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
++ << " server. Only failed calls to existing DCOP servers will"
++ << " generate an error message. If no DCOP server is available" << endl
++ << " at all, no error will be generated." << endl;
++
++ exit( exitCode );
++ }
+
+! /**
+! * Return a list of all users and their home directories.
+! * Returns an empty list if /etc/passwd cannot be read for some reason.
+! */
+! static UserList userList()
+ {
++ UserList result;
++
++ QFile f( "/etc/passwd" );
++
++ if( !f.open( IO_ReadOnly ) )
++ {
++ cerr << "Can't open /etc/passwd for reading!" << endl;
++ return result;
++ }
+
+! QStringList l( QStringList::split( '\n', f.readAll() ) );
+!
+! for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
+! {
+! QStringList userInfo( QStringList::split( ':', *it, true ) );
+! result[ userInfo[ 0 ] ] = userInfo[ 5 ];
+ }
+
+! return result;
+! }
+!
+! /**
+! * Return a list of available DCOP sessions for the specified user
+! * An empty list means no sessions are available, or an error occurred.
+! */
+! QStringList dcopSessionList( const QString &user, const QString &home )
+! {
+! if( home.isEmpty() )
+! {
+! cerr << "WARNING: Cannot determine home directory for user "
+! << user << "!" << endl
+! << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
+! << "calling dcop." << endl;
+! return QStringList();
+! }
+!
+! QStringList result;
+! QFileInfo dirInfo( home );
+! if( !dirInfo.exists() || !dirInfo.isReadable() )
+! return result;
+!
+! QDir d( home );
+! d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
+! d.setNameFilter( ".DCOPserver*" );
+!
+! const QFileInfoList *list = d.entryInfoList();
+! if( !list )
+! return result;
+!
+! QFileInfoListIterator it( *list );
+! QFileInfo *fi;
+!
+! while ( ( fi = it.current() ) != 0 )
+! {
+! if( fi->isReadable() )
+! result.append( fi->fileName() );
+! ++it;
+! }
+! return result;
+! }
+
++ /**
++ * Do the actual DCOP call
++ */
++ void runDCOP( QCStringList args, UserList users, Session session,
++ const QString sessionName, bool readStdin )
++ {
+ QCString app;
+ QCString objid;
+ QCString function;
+! QCStringList params;
+! DCOPClient *client = 0L;
+! if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
+ {
+! // WARNING: This part (until the closing '}') could very
+! // well be broken now. As I don't know how to trigger and test
+! // dcoprefs this code is *not* tested. It compiles and it looks
+! // ok to me, but that's all I can say - Martijn (2001/12/24)
+! int delimPos = args[ 0 ].findRev( ',' );
+! if( delimPos == -1 )
+! {
+! cerr << "Error: '" << args[ 0 ]
+! << "' is not a valid DCOP reference." << endl;
+! exit( -1 );
+! }
+! args[ 0 ][ delimPos ] = 0;
+! app = args[ 0 ].mid( 8 );
+! delimPos++;
+! args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
+! objid = args[ 0 ].mid( delimPos );
+! if( args.count() > 1 )
+! function = args[ 1 ];
+! if( args.count() > 2 )
+! {
+! params = args;
+! params.remove( params.begin() );
+! params.remove( params.begin() );
+! }
+ }
+ else
+ {
+! if( !args.isEmpty() )
+! app = args[ 0 ];
+! if( args.count() > 1 )
+! objid = args[ 1 ];
+! if( args.count() > 2 )
+! function = args[ 2 ];
+! if( args.count() > 3)
+! {
+! params = args;
+! params.remove( params.begin() );
+! params.remove( params.begin() );
+! params.remove( params.begin() );
+! }
+! }
+!
+! bool firstRun = true;
+! UserList::Iterator it;
+! QStringList sessions;
+! bool presetDCOPServer = false;
+! // char *dcopStr = 0L;
+! QString dcopServer;
+!
+! for( it = users.begin(); it != users.end() || firstRun; it++ )
+! {
+! firstRun = false;
+!
+! //cout << "Iterating '" << it.key() << "'" << endl;
+!
+! if( session == QuerySessions )
+! {
+! QStringList sessions = dcopSessionList( it.key(), it.data() );
+! if( sessions.isEmpty() )
+! {
+! cout << "No active sessions";
+! if( !( *it ).isEmpty() )
+! cout << " for user " << *it;
+! cout << endl;
+! }
+! else
+! {
+! cout << "Active sessions ";
+! if( !( *it ).isEmpty() )
+! cout << "for user " << *it << " ";
+! cout << ":" << endl;
+!
+! QStringList::Iterator sIt;
+! for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
+! cout << " " << *sIt << endl;
+!
+! cout << endl;
+! }
+! continue;
+! }
+!
+! if( getenv( "DCOPSERVER" ) )
+! {
+! sessions.append( getenv( "DCOPSERVER" ) );
+! presetDCOPServer = true;
+! }
+!
+! if( users.count() > 1 || ( users.count() == 1 &&
+! ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
+! {
+! sessions = dcopSessionList( it.key(), it.data() );
+! if( sessions.isEmpty() )
+! {
+! if( users.count() > 1 )
+! continue;
+! else
+! {
+! cerr << "ERROR: No active KDE sessions!" << endl
+! << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
+! << "before calling dcop." << endl;
+! exit( -1 );
+! }
+! }
+! else if( sessions.count() > 1 && session != AllSessions )
+! {
+! cerr << "ERROR: Multiple available KDE sessions!" << endl
+! << "Please specify the correct session to use with --session or use the" << endl
+! << "--all-sessions option to broadcast to all sessions." << endl;
+! exit( -1 );
+! }
+! }
+
++ if( users.count() > 1 || ( users.count() == 1 &&
++ ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
++ {
++ // Check for ICE authority file and if the file can be read by us
++ QString home = it.data();
++ QString iceFile = it.data() + "/.ICEauthority";
++ QFileInfo fi( iceFile );
++ if( iceFile.isEmpty() )
++ {
++ cerr << "WARNING: Cannot determine home directory for user "
++ << it.key() << "!" << endl
++ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
++ << "calling dcop." << endl;
++ }
++ else if( fi.exists() )
++ {
++ if( fi.isReadable() )
++ {
++ char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
++ putenv( envStr );
++ //cerr << "ice: " << envStr << endl;
++ }
++ else
++ {
++ cerr << "WARNING: ICE authority file " << iceFile
++ << "is not readable by you!" << endl
++ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
++ << "calling dcop." << endl;
++ }
++ }
++ else
++ {
++ if( users.count() > 1 )
++ continue;
++ else
++ {
++ cerr << "WARNING: Cannot find ICE authority file "
++ << iceFile << "!" << endl
++ << "Please check permissions or set the $ICEAUTHORITY"
++ << " variable manually before" << endl
++ << "calling dcop." << endl;
++ }
++ }
++ }
++
++ // Main loop
++ // If users is an empty list we're calling for the currently logged
++ // in user. In this case we don't have a session, but still want
++ // to iterate the loop once.
++ QStringList::Iterator sIt = sessions.begin();
++ for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
++ {
++ if( !presetDCOPServer && !users.isEmpty() )
++ {
++ QString dcopFile = it.data() + "/" + *sIt;
++ QFile f( dcopFile );
++ if( !f.open( IO_ReadOnly ) )
++ {
++ cerr << "Can't open " << dcopFile << " for reading!" << endl;
++ exit( -1 );
++ }
++
++ QStringList l( QStringList::split( '\n', f.readAll() ) );
++ dcopServer = l.first();
++
++ if( dcopServer.isEmpty() )
++ {
++ cerr << "WARNING: Unable to determine DCOP server for session "
++ << *sIt << "!" << endl
++ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
++ << "calling dcop." << endl;
++ exit( -1 );
++ }
++ }
++
++ delete client;
++ client = new DCOPClient;
++ if( !dcopServer.isEmpty() )
++ client->setServerAddress( dcopServer.ascii() );
++ bool success = client->attach();
++ if( !success )
++ {
++ cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
++ continue;
++ }
++ dcop = client;
++
++ switch ( args.count() )
++ {
++ case 0:
++ queryApplications("");
++ break;
++ case 1:
++ if (endsWith(app, '*'))
++ queryApplications(app);
++ else
++ queryObjects( app, "" );
++ break;
++ case 2:
++ if (endsWith(objid, '*'))
++ queryObjects(app, objid);
++ else
++ queryFunctions( app, objid );
++ break;
++ case 3:
++ default:
++ if( readStdin )
++ {
++ QCStringList::Iterator replaceArg = args.end();
++
++ QCStringList::Iterator it;
++ for( it = args.begin(); it != args.end(); it++ )
++ if( *it == "%1" )
++ replaceArg = it;
++
++ // Read from stdin until EOF and call function for each line read
++ char *buf = new char[ 1000 ];
++ while ( !feof( stdin ) )
++ {
++ fgets( buf, 1000, stdin );
++
++ if( replaceArg != args.end() )
++ *replaceArg = buf;
++
++ callFunction( app, objid, function, params );
++ }
++ }
++ else
++ {
++ // Just call function
++ // cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
++ callFunction( app, objid, function, params );
++ }
++ break;
++ }
++ // Another sIt++ would make the loop infinite...
++ if( users.isEmpty() )
++ break;
++ }
++
++ // Another it++ would make the loop infinite...
++ if( it == users.end() )
++ break;
+ }
++ }
++
+
++ int main( int argc, char** argv )
++ {
++ bool readStdin = false;
++ int numOptions = 0;
++ QString user;
++ Session session = DefaultSession;
++ QString sessionName;
++
++ // Scan for command-line options first
++ for( int pos = 1 ; pos <= argc - 1 ; pos++ )
++ {
++ if( strcmp( argv[ pos ], "--help" ) == 0 )
++ showHelp( 0 );
++ else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
++ {
++ readStdin = true;
++ numOptions++;
++ }
++ else if( strcmp( argv[ pos ], "--user" ) == 0 )
++ {
++ if( pos <= argc - 2 )
++ {
++ user = QString::fromLocal8Bit( argv[ pos + 1] );
++ numOptions +=2;
++ pos++;
++ }
++ else
++ {
++ cerr << "Missing username for '--user' option!" << endl << endl;
++ showHelp( -1 );
++ }
++ }
++ else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
++ {
++ user = "*";
++ numOptions ++;
++ }
++ else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
++ {
++ session = QuerySessions;
++ numOptions ++;
++ }
++ else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
++ {
++ session = AllSessions;
++ numOptions ++;
++ }
++ else if( argv[ pos ][ 0 ] == '-' )
++ {
++ cerr << "Unknown command-line option '" << argv[ pos ]
++ << "'." << endl << endl;
++ showHelp( -1 );
++ }
++ else
++ break; // End of options
++ }
++
++ argc -= numOptions;
++
++ QCStringList args;
++ for( int i = numOptions; i < argc + numOptions - 1; i++ )
++ args.append( argv[ i + 1 ] );
++
++ if( readStdin && args.count() < 3 )
++ {
++ cerr << "--pipe option only supported for function calls!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ if( user == "*" && args.count() < 3 && session != QuerySessions )
++ {
++ cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ if( session == QuerySessions && !args.isEmpty() )
++ {
++ cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ if( session == QuerySessions && user.isEmpty() )
++ {
++ cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
++ << "--all-users options!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ if( session != DefaultSession && session != QuerySessions &&
++ args.count() < 3 )
++ {
++ cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
++ << "calls!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ UserList users;
++ if( user == "*" )
++ users = userList();
++ else if( !user.isEmpty() )
++ users[ user ] = userList()[ user ];
++
++ runDCOP( args, users, session, sessionName, readStdin );
++
+ return 0;
+ }
++
++ // vim: set ts=8 sts=4 sw=4 noet:
++
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -c -r1.2 dcopfind.cpp
+*** client/dcopfind.cpp 2001/10/31 01:17:39 1.2
+--- client/dcopfind.cpp 2002/01/16 18:06:24
+***************
+*** 36,42 ****
+ static bool bAppIdOnly = 0;
+ static bool bLaunchApp = 0;
+
+! bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
+ {
+ QString f = func; // Qt is better with unicode strings, so use one.
+ int left = f.find( '(' );
+--- 36,42 ----
+ static bool bAppIdOnly = 0;
+ static bool bLaunchApp = 0;
+
+! bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+ {
+ QString f = func; // Qt is better with unicode strings, so use one.
+ int left = f.find( '(' );
+***************
+*** 118,124 ****
+ f = fc;
+ }
+
+! if ( (int) types.count() != argc ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+--- 118,124 ----
+ f = fc;
+ }
+
+! if ( types.count() != args.count() ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+***************
+*** 128,136 ****
+
+ int i = 0;
+ for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
+! marshall(arg, argc, args, i, *it);
+ }
+! if ( (int) i != argc ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+--- 128,136 ----
+
+ int i = 0;
+ for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
+! marshall(arg, args, i, *it);
+ }
+! if ( (uint) i != args.count() ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+***************
+*** 221,227 ****
+ argc = 0;
+ }
+
+! findObject( app, objid, function, argc, args );
+
+ return 0;
+ }
+--- 221,231 ----
+ argc = 0;
+ }
+
+! QCStringList params;
+! for( int i = 0; i < argc; i++ )
+! params.append( args[ i ] );
+!
+! findObject( app, objid, function, params );
+
+ return 0;
+ }
+Index: client/marshall.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/marshall.cpp,v
+retrieving revision 1.3
+diff -c -r1.3 marshall.cpp
+*** client/marshall.cpp 2001/10/31 01:17:39 1.3
+--- client/marshall.cpp 2002/01/16 18:06:24
+***************
+*** 242,349 ****
+
+ }
+
+! void marshall(QDataStream &arg, int argc, char **argv, int &i, QString type)
+ {
+! if (type == "QStringList")
+! type = "QValueList<QString>";
+! if (type == "QCStringList")
+! type = "QValueList<QCString>";
+! if (i >= argc)
+! {
+! qWarning("Not enough arguments.");
+! exit(1);
+! }
+! QString s = QString::fromLocal8Bit(argv[i]);
+!
+! if ( type == "int" )
+! arg << s.toInt();
+! else if ( type == "uint" )
+! arg << s.toUInt();
+! else if ( type == "unsigned" )
+! arg << s.toUInt();
+! else if ( type == "unsigned int" )
+! arg << s.toUInt();
+! else if ( type == "long" )
+! arg << s.toLong();
+! else if ( type == "long int" )
+! arg << s.toLong();
+! else if ( type == "unsigned long" )
+! arg << s.toULong();
+! else if ( type == "unsigned long int" )
+! arg << s.toULong();
+! else if ( type == "float" )
+! arg << s.toFloat();
+! else if ( type == "double" )
+! arg << s.toDouble();
+! else if ( type == "bool" )
+! arg << mkBool( s );
+! else if ( type == "QString" )
+! arg << s;
+! else if ( type == "QCString" )
+! arg << QCString( argv[i] );
+! else if ( type == "QColor" )
+! arg << mkColor( s );
+! else if ( type == "QPoint" )
+! arg << mkPoint( s );
+! else if ( type == "QSize" )
+! arg << mkSize( s );
+! else if ( type == "QRect" )
+! arg << mkRect( s );
+! else if ( type == "QVariant" ) {
+! if ( s == "true" || s == "false" )
+! arg << QVariant( mkBool( s ), 42 );
+! else if ( s.left( 4 ) == "int(" )
+! arg << QVariant( s.mid(4, s.length()-5).toInt() );
+! else if ( s.left( 7 ) == "QPoint(" )
+! arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
+! else if ( s.left( 6 ) == "QSize(" )
+! arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
+! else if ( s.left( 6 ) == "QRect(" )
+! arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
+! else if ( s.left( 7 ) == "QColor(" )
+! arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
+! else
+! arg << QVariant( s );
+! } else if ( type.startsWith("QValueList<")) {
+! type = type.mid(11, type.length() - 12);
+! QStringList list;
+! QString delim = s;
+! if (delim == "[")
+! delim = "]";
+! if (delim == "(")
+! delim = ")";
+! i++;
+! QByteArray dummy_data;
+! QDataStream dummy_arg(dummy_data, IO_WriteOnly);
+
+! int j = i;
+! int count = 0;
+! // Parse list to get the count
+! while (true) {
+! if (j >= argc)
+! {
+! qWarning("List end-delimiter '%s' not found.", delim.latin1());
+! exit(1);
+! }
+! if (argv[j] == delim) break;
+! marshall(dummy_arg, argc, argv, j, type);
+! count++;
+! }
+! arg << (Q_UINT32) count;
+! // Parse the list for real
+! while (true) {
+! if (i >= argc)
+! {
+! qWarning("List end-delimiter '%s' not found.", delim.latin1());
+! exit(1);
+! }
+! if (argv[i] == delim) break;
+! marshall(arg, argc, argv, i, type);
+! }
+! } else {
+! qWarning( "cannot handle datatype '%s'", type.latin1() );
+! exit(1);
+! }
+ i++;
+ }
+
+--- 242,351 ----
+
+ }
+
+! void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
+ {
+! if (type == "QStringList")
+! type = "QValueList<QString>";
+! if (type == "QCStringList")
+! type = "QValueList<QCString>";
+! if( i > args.count() )
+! {
+! qWarning("Not enough arguments.");
+! exit(1);
+! }
+! QString s = QString::fromLocal8Bit( args[ i ] );
+
+! if ( type == "int" )
+! arg << s.toInt();
+! else if ( type == "uint" )
+! arg << s.toUInt();
+! else if ( type == "unsigned" )
+! arg << s.toUInt();
+! else if ( type == "unsigned int" )
+! arg << s.toUInt();
+! else if ( type == "long" )
+! arg << s.toLong();
+! else if ( type == "long int" )
+! arg << s.toLong();
+! else if ( type == "unsigned long" )
+! arg << s.toULong();
+! else if ( type == "unsigned long int" )
+! arg << s.toULong();
+! else if ( type == "float" )
+! arg << s.toFloat();
+! else if ( type == "double" )
+! arg << s.toDouble();
+! else if ( type == "bool" )
+! arg << mkBool( s );
+! else if ( type == "QString" )
+! arg << s;
+! else if ( type == "QCString" )
+! arg << QCString( args[ i ] );
+! else if ( type == "QColor" )
+! arg << mkColor( s );
+! else if ( type == "QPoint" )
+! arg << mkPoint( s );
+! else if ( type == "QSize" )
+! arg << mkSize( s );
+! else if ( type == "QRect" )
+! arg << mkRect( s );
+! else if ( type == "QVariant" ) {
+! if ( s == "true" || s == "false" )
+! arg << QVariant( mkBool( s ), 42 );
+! else if ( s.left( 4 ) == "int(" )
+! arg << QVariant( s.mid(4, s.length()-5).toInt() );
+! else if ( s.left( 7 ) == "QPoint(" )
+! arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
+! else if ( s.left( 6 ) == "QSize(" )
+! arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
+! else if ( s.left( 6 ) == "QRect(" )
+! arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
+! else if ( s.left( 7 ) == "QColor(" )
+! arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
+! else
+! arg << QVariant( s );
+! } else if ( type.startsWith("QValueList<")) {
+! type = type.mid(11, type.length() - 12);
+! QStringList list;
+! QString delim = s;
+! if (delim == "[")
+! delim = "]";
+! if (delim == "(")
+! delim = ")";
+ i++;
++ QByteArray dummy_data;
++ QDataStream dummy_arg(dummy_data, IO_WriteOnly);
++
++ uint j = i;
++ uint count = 0;
++ // Parse list to get the count
++ while (true) {
++ if( j > args.count() )
++ {
++ qWarning("List end-delimiter '%s' not found.", delim.latin1());
++ exit(1);
++ }
++ if( QString::fromLocal8Bit( args[ j ] ) == delim )
++ break;
++ marshall( dummy_arg, args, j, type );
++ count++;
++ }
++ arg << (Q_UINT32) count;
++ // Parse the list for real
++ while (true) {
++ if( i > args.count() )
++ {
++ qWarning("List end-delimiter '%s' not found.", delim.latin1());
++ exit(1);
++ }
++ if( QString::fromLocal8Bit( args[ i ] ) == delim )
++ break;
++ marshall( arg, args, i, type );
++ }
++ } else {
++ qWarning( "cannot handle datatype '%s'", type.latin1() );
++ exit(1);
++ }
++ i++;
+ }
+
diff --git a/kompare/tests/cvsdiff/ed.diff b/kompare/tests/cvsdiff/ed.diff
new file mode 100644
index 00000000..2c859e61
--- /dev/null
+++ b/kompare/tests/cvsdiff/ed.diff
@@ -0,0 +1,24 @@
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -e -r1.2 dcopfind.cpp
+224c
+ QCStringList params;
+ for( int i = 0; i < argc; i++ )
+ params.append( args[ i ] );
+
+ findObject( app, objid, function, params );
+.
+133c
+ if ( (uint) i != args.count() ) {
+.
+131c
+ marshall(arg, args, i, *it);
+.
+121c
+ if ( types.count() != args.count() ) {
+.
+39c
+bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+.
diff --git a/kompare/tests/cvsdiff/edm.diff b/kompare/tests/cvsdiff/edm.diff
new file mode 100644
index 00000000..0fb04575
--- /dev/null
+++ b/kompare/tests/cvsdiff/edm.diff
@@ -0,0 +1,692 @@
+Index: client/dcop.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcop.cpp,v
+retrieving revision 1.26
+diff -e -r1.26 dcop.cpp
+343a
+
+// vim: set ts=8 sts=4 sw=4 noet:
+
+.
+340a
+}
+
+
+int main( int argc, char** argv )
+{
+ bool readStdin = false;
+ int numOptions = 0;
+ QString user;
+ Session session = DefaultSession;
+ QString sessionName;
+
+ // Scan for command-line options first
+ for( int pos = 1 ; pos <= argc - 1 ; pos++ )
+ {
+ if( strcmp( argv[ pos ], "--help" ) == 0 )
+ showHelp( 0 );
+ else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
+ {
+ readStdin = true;
+ numOptions++;
+ }
+ else if( strcmp( argv[ pos ], "--user" ) == 0 )
+ {
+ if( pos <= argc - 2 )
+ {
+ user = QString::fromLocal8Bit( argv[ pos + 1] );
+ numOptions +=2;
+ pos++;
+ }
+ else
+ {
+ cerr << "Missing username for '--user' option!" << endl << endl;
+ showHelp( -1 );
+ }
+ }
+ else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
+ {
+ user = "*";
+ numOptions ++;
+ }
+ else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
+ {
+ session = QuerySessions;
+ numOptions ++;
+ }
+ else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
+ {
+ session = AllSessions;
+ numOptions ++;
+ }
+ else if( argv[ pos ][ 0 ] == '-' )
+ {
+ cerr << "Unknown command-line option '" << argv[ pos ]
+ << "'." << endl << endl;
+ showHelp( -1 );
+ }
+ else
+ break; // End of options
+ }
+
+ argc -= numOptions;
+
+ QCStringList args;
+ for( int i = numOptions; i < argc + numOptions - 1; i++ )
+ args.append( argv[ i + 1 ] );
+
+ if( readStdin && args.count() < 3 )
+ {
+ cerr << "--pipe option only supported for function calls!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ if( user == "*" && args.count() < 3 && session != QuerySessions )
+ {
+ cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ if( session == QuerySessions && !args.isEmpty() )
+ {
+ cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ if( session == QuerySessions && user.isEmpty() )
+ {
+ cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
+ << "--all-users options!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ if( session != DefaultSession && session != QuerySessions &&
+ args.count() < 3 )
+ {
+ cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
+ << "calls!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ UserList users;
+ if( user == "*" )
+ users = userList();
+ else if( !user.isEmpty() )
+ users[ user ] = userList()[ user ];
+
+ runDCOP( args, users, session, sessionName, readStdin );
+.
+339a
+ if( users.count() > 1 || ( users.count() == 1 &&
+ ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
+ {
+ // Check for ICE authority file and if the file can be read by us
+ QString home = it.data();
+ QString iceFile = it.data() + "/.ICEauthority";
+ QFileInfo fi( iceFile );
+ if( iceFile.isEmpty() )
+ {
+ cerr << "WARNING: Cannot determine home directory for user "
+ << it.key() << "!" << endl
+ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
+ << "calling dcop." << endl;
+ }
+ else if( fi.exists() )
+ {
+ if( fi.isReadable() )
+ {
+ char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
+ putenv( envStr );
+ //cerr << "ice: " << envStr << endl;
+ }
+ else
+ {
+ cerr << "WARNING: ICE authority file " << iceFile
+ << "is not readable by you!" << endl
+ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
+ << "calling dcop." << endl;
+ }
+ }
+ else
+ {
+ if( users.count() > 1 )
+ continue;
+ else
+ {
+ cerr << "WARNING: Cannot find ICE authority file "
+ << iceFile << "!" << endl
+ << "Please check permissions or set the $ICEAUTHORITY"
+ << " variable manually before" << endl
+ << "calling dcop." << endl;
+ }
+ }
+ }
+
+ // Main loop
+ // If users is an empty list we're calling for the currently logged
+ // in user. In this case we don't have a session, but still want
+ // to iterate the loop once.
+ QStringList::Iterator sIt = sessions.begin();
+ for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
+ {
+ if( !presetDCOPServer && !users.isEmpty() )
+ {
+ QString dcopFile = it.data() + "/" + *sIt;
+ QFile f( dcopFile );
+ if( !f.open( IO_ReadOnly ) )
+ {
+ cerr << "Can't open " << dcopFile << " for reading!" << endl;
+ exit( -1 );
+ }
+
+ QStringList l( QStringList::split( '\n', f.readAll() ) );
+ dcopServer = l.first();
+
+ if( dcopServer.isEmpty() )
+ {
+ cerr << "WARNING: Unable to determine DCOP server for session "
+ << *sIt << "!" << endl
+ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
+ << "calling dcop." << endl;
+ exit( -1 );
+ }
+ }
+
+ delete client;
+ client = new DCOPClient;
+ if( !dcopServer.isEmpty() )
+ client->setServerAddress( dcopServer.ascii() );
+ bool success = client->attach();
+ if( !success )
+ {
+ cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
+ continue;
+ }
+ dcop = client;
+
+ switch ( args.count() )
+ {
+ case 0:
+ queryApplications("");
+ break;
+ case 1:
+ if (endsWith(app, '*'))
+ queryApplications(app);
+ else
+ queryObjects( app, "" );
+ break;
+ case 2:
+ if (endsWith(objid, '*'))
+ queryObjects(app, objid);
+ else
+ queryFunctions( app, objid );
+ break;
+ case 3:
+ default:
+ if( readStdin )
+ {
+ QCStringList::Iterator replaceArg = args.end();
+
+ QCStringList::Iterator it;
+ for( it = args.begin(); it != args.end(); it++ )
+ if( *it == "%1" )
+ replaceArg = it;
+
+ // Read from stdin until EOF and call function for each line read
+ char *buf = new char[ 1000 ];
+ while ( !feof( stdin ) )
+ {
+ fgets( buf, 1000, stdin );
+
+ if( replaceArg != args.end() )
+ *replaceArg = buf;
+
+ callFunction( app, objid, function, params );
+ }
+ }
+ else
+ {
+ // Just call function
+// cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
+ callFunction( app, objid, function, params );
+ }
+ break;
+ }
+ // Another sIt++ would make the loop infinite...
+ if( users.isEmpty() )
+ break;
+ }
+
+ // Another it++ would make the loop infinite...
+ if( it == users.end() )
+ break;
+.
+308,338c
+ if( !args.isEmpty() )
+ app = args[ 0 ];
+ if( args.count() > 1 )
+ objid = args[ 1 ];
+ if( args.count() > 2 )
+ function = args[ 2 ];
+ if( args.count() > 3)
+ {
+ params = args;
+ params.remove( params.begin() );
+ params.remove( params.begin() );
+ params.remove( params.begin() );
+ }
+ }
+
+ bool firstRun = true;
+ UserList::Iterator it;
+ QStringList sessions;
+ bool presetDCOPServer = false;
+// char *dcopStr = 0L;
+ QString dcopServer;
+
+ for( it = users.begin(); it != users.end() || firstRun; it++ )
+ {
+ firstRun = false;
+
+ //cout << "Iterating '" << it.key() << "'" << endl;
+
+ if( session == QuerySessions )
+ {
+ QStringList sessions = dcopSessionList( it.key(), it.data() );
+ if( sessions.isEmpty() )
+ {
+ cout << "No active sessions";
+ if( !( *it ).isEmpty() )
+ cout << " for user " << *it;
+ cout << endl;
+ }
+ else
+ {
+ cout << "Active sessions ";
+ if( !( *it ).isEmpty() )
+ cout << "for user " << *it << " ";
+ cout << ":" << endl;
+
+ QStringList::Iterator sIt;
+ for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
+ cout << " " << *sIt << endl;
+
+ cout << endl;
+ }
+ continue;
+ }
+
+ if( getenv( "DCOPSERVER" ) )
+ {
+ sessions.append( getenv( "DCOPSERVER" ) );
+ presetDCOPServer = true;
+ }
+
+ if( users.count() > 1 || ( users.count() == 1 &&
+ ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
+ {
+ sessions = dcopSessionList( it.key(), it.data() );
+ if( sessions.isEmpty() )
+ {
+ if( users.count() > 1 )
+ continue;
+ else
+ {
+ cerr << "ERROR: No active KDE sessions!" << endl
+ << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
+ << "before calling dcop." << endl;
+ exit( -1 );
+ }
+ }
+ else if( sessions.count() > 1 && session != AllSessions )
+ {
+ cerr << "ERROR: Multiple available KDE sessions!" << endl
+ << "Please specify the correct session to use with --session or use the" << endl
+ << "--all-sessions option to broadcast to all sessions." << endl;
+ exit( -1 );
+ }
+ }
+.
+289,304c
+ // WARNING: This part (until the closing '}') could very
+ // well be broken now. As I don't know how to trigger and test
+ // dcoprefs this code is *not* tested. It compiles and it looks
+ // ok to me, but that's all I can say - Martijn (2001/12/24)
+ int delimPos = args[ 0 ].findRev( ',' );
+ if( delimPos == -1 )
+ {
+ cerr << "Error: '" << args[ 0 ]
+ << "' is not a valid DCOP reference." << endl;
+ exit( -1 );
+ }
+ args[ 0 ][ delimPos ] = 0;
+ app = args[ 0 ].mid( 8 );
+ delimPos++;
+ args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
+ objid = args[ 0 ].mid( delimPos );
+ if( args.count() > 1 )
+ function = args[ 1 ];
+ if( args.count() > 2 )
+ {
+ params = args;
+ params.remove( params.begin() );
+ params.remove( params.begin() );
+ }
+.
+286,287c
+ QCStringList params;
+ DCOPClient *client = 0L;
+ if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
+.
+282a
+/**
+ * Do the actual DCOP call
+ */
+void runDCOP( QCStringList args, UserList users, Session session,
+ const QString sessionName, bool readStdin )
+{
+.
+279,281c
+ return result;
+}
+
+/**
+ * Return a list of available DCOP sessions for the specified user
+ * An empty list means no sessions are available, or an error occurred.
+ */
+QStringList dcopSessionList( const QString &user, const QString &home )
+{
+ if( home.isEmpty() )
+ {
+ cerr << "WARNING: Cannot determine home directory for user "
+ << user << "!" << endl
+ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
+ << "calling dcop." << endl;
+ return QStringList();
+ }
+
+ QStringList result;
+ QFileInfo dirInfo( home );
+ if( !dirInfo.exists() || !dirInfo.isReadable() )
+ return result;
+
+ QDir d( home );
+ d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
+ d.setNameFilter( ".DCOPserver*" );
+
+ const QFileInfoList *list = d.entryInfoList();
+ if( !list )
+ return result;
+
+ QFileInfoListIterator it( *list );
+ QFileInfo *fi;
+
+ while ( ( fi = it.current() ) != 0 )
+ {
+ if( fi->isReadable() )
+ result.append( fi->fileName() );
+ ++it;
+ }
+ return result;
+}
+.
+274,276c
+ QStringList l( QStringList::split( '\n', f.readAll() ) );
+
+ for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
+ {
+ QStringList userInfo( QStringList::split( ':', *it, true ) );
+ result[ userInfo[ 0 ] ] = userInfo[ 5 ];
+.
+272a
+ UserList result;
+
+ QFile f( "/etc/passwd" );
+
+ if( !f.open( IO_ReadOnly ) )
+ {
+ cerr << "Can't open /etc/passwd for reading!" << endl;
+ return result;
+ }
+.
+270,271c
+/**
+ * Return a list of all users and their home directories.
+ * Returns an empty list if /etc/passwd cannot be read for some reason.
+ */
+static UserList userList()
+.
+268a
+/**
+ * Show command-line help and exit
+ */
+void showHelp( int exitCode = 0 )
+{
+ cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
+ << "" << endl
+ << "Console DCOP client" << endl
+ << "" << endl
+ << "Generic options:" << endl
+ << " --help Show help about options" << endl
+ << "" << endl
+ << "Options:" << endl
+ << " --pipe Call DCOP for each line read from stdin" << endl
+ << " --user <user> Connect to the given user's DCOP server. This option will" << endl
+ << " ignore the values of the environment vars $DCOPSERVER and" << endl
+ << " $ICEAUTHORITY, even if they are set." << endl
+ << " If the user has more than one open session, you must also" << endl
+ << " use one of the --list-sessions, --session or --als-sessions" << endl
+ << " command-line options." << endl
+ << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
+ << " server. Only failed calls to existing DCOP servers will"
+ << " generate an error message. If no DCOP server is available" << endl
+ << " at all, no error will be generated." << endl;
+
+ exit( exitCode );
+}
+.
+246,250c
+ uint i = 0;
+ for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
+ marshall( arg, args, i, *it );
+
+ if ( i != args.count() )
+ {
+.
+164c
+// exit(1);
+ return;
+.
+156,157c
+ uint a = (*it).contains(',');
+ if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
+.
+139c
+ if ( !ok && args.isEmpty() )
+.
+123d
+121c
+void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
+.
+35a
+static QTextStream cout( stdout, IO_WriteOnly );
+static QTextStream cerr( stderr, IO_WriteOnly );
+
+/**
+ * Session to send call to
+ * DefaultSession - current session. Current KDE session when called without
+ * --user or --all-users option. Otherwise this value ignores
+ * all users with more than one active session.
+ * AllSessions - Send to all sessions found. requires --user or --all-users.
+ * QuerySessions - Don't call DCOP, return a list of available sessions.
+ * CustomSession - Use the specified session
+ */
+enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
+
+.
+33a
+typedef QMap<QString, QString> UserList;
+
+.
+28,30c
+#include "../kdatastream.h"
+.
+25c
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qmap.h>
+#include <qstringlist.h>
+#include <qtextstream.h>
+#include <qvariant.h>
+
+// putenv() is not available on all platforms, so make sure the emulation
+// wrapper is available in those cases by loading config.h!
+#include <config.h>
+
+.
+23c
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+.
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -e -r1.2 dcopfind.cpp
+224c
+ QCStringList params;
+ for( int i = 0; i < argc; i++ )
+ params.append( args[ i ] );
+
+ findObject( app, objid, function, params );
+.
+133c
+ if ( (uint) i != args.count() ) {
+.
+131c
+ marshall(arg, args, i, *it);
+.
+121c
+ if ( types.count() != args.count() ) {
+.
+39c
+bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+.
+Index: client/marshall.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/marshall.cpp,v
+retrieving revision 1.3
+diff -e -r1.3 marshall.cpp
+347a
+ QByteArray dummy_data;
+ QDataStream dummy_arg(dummy_data, IO_WriteOnly);
+
+ uint j = i;
+ uint count = 0;
+ // Parse list to get the count
+ while (true) {
+ if( j > args.count() )
+ {
+ qWarning("List end-delimiter '%s' not found.", delim.latin1());
+ exit(1);
+ }
+ if( QString::fromLocal8Bit( args[ j ] ) == delim )
+ break;
+ marshall( dummy_arg, args, j, type );
+ count++;
+ }
+ arg << (Q_UINT32) count;
+ // Parse the list for real
+ while (true) {
+ if( i > args.count() )
+ {
+ qWarning("List end-delimiter '%s' not found.", delim.latin1());
+ exit(1);
+ }
+ if( QString::fromLocal8Bit( args[ i ] ) == delim )
+ break;
+ marshall( arg, args, i, type );
+ }
+ } else {
+ qWarning( "cannot handle datatype '%s'", type.latin1() );
+ exit(1);
+ }
+ i++;
+.
+319,346c
+ if ( type == "int" )
+ arg << s.toInt();
+ else if ( type == "uint" )
+ arg << s.toUInt();
+ else if ( type == "unsigned" )
+ arg << s.toUInt();
+ else if ( type == "unsigned int" )
+ arg << s.toUInt();
+ else if ( type == "long" )
+ arg << s.toLong();
+ else if ( type == "long int" )
+ arg << s.toLong();
+ else if ( type == "unsigned long" )
+ arg << s.toULong();
+ else if ( type == "unsigned long int" )
+ arg << s.toULong();
+ else if ( type == "float" )
+ arg << s.toFloat();
+ else if ( type == "double" )
+ arg << s.toDouble();
+ else if ( type == "bool" )
+ arg << mkBool( s );
+ else if ( type == "QString" )
+ arg << s;
+ else if ( type == "QCString" )
+ arg << QCString( args[ i ] );
+ else if ( type == "QColor" )
+ arg << mkColor( s );
+ else if ( type == "QPoint" )
+ arg << mkPoint( s );
+ else if ( type == "QSize" )
+ arg << mkSize( s );
+ else if ( type == "QRect" )
+ arg << mkRect( s );
+ else if ( type == "QVariant" ) {
+ if ( s == "true" || s == "false" )
+ arg << QVariant( mkBool( s ), 42 );
+ else if ( s.left( 4 ) == "int(" )
+ arg << QVariant( s.mid(4, s.length()-5).toInt() );
+ else if ( s.left( 7 ) == "QPoint(" )
+ arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
+ else if ( s.left( 6 ) == "QSize(" )
+ arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
+ else if ( s.left( 6 ) == "QRect(" )
+ arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
+ else if ( s.left( 7 ) == "QColor(" )
+ arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
+ else
+ arg << QVariant( s );
+ } else if ( type.startsWith("QValueList<")) {
+ type = type.mid(11, type.length() - 12);
+ QStringList list;
+ QString delim = s;
+ if (delim == "[")
+ delim = "]";
+ if (delim == "(")
+ delim = ")";
+.
+247,317c
+ if (type == "QStringList")
+ type = "QValueList<QString>";
+ if (type == "QCStringList")
+ type = "QValueList<QCString>";
+ if( i > args.count() )
+ {
+ qWarning("Not enough arguments.");
+ exit(1);
+ }
+ QString s = QString::fromLocal8Bit( args[ i ] );
+.
+245c
+void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
+.
diff --git a/kompare/tests/cvsdiff/normal.diff b/kompare/tests/cvsdiff/normal.diff
new file mode 100644
index 00000000..3becb815
--- /dev/null
+++ b/kompare/tests/cvsdiff/normal.diff
@@ -0,0 +1,29 @@
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -r1.2 dcopfind.cpp
+39c39
+< bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
+---
+> bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+121c121
+< if ( (int) types.count() != argc ) {
+---
+> if ( types.count() != args.count() ) {
+131c131
+< marshall(arg, argc, args, i, *it);
+---
+> marshall(arg, args, i, *it);
+133c133
+< if ( (int) i != argc ) {
+---
+> if ( (uint) i != args.count() ) {
+224c224,228
+< findObject( app, objid, function, argc, args );
+---
+> QCStringList params;
+> for( int i = 0; i < argc; i++ )
+> params.append( args[ i ] );
+>
+> findObject( app, objid, function, params );
diff --git a/kompare/tests/cvsdiff/normalm.diff b/kompare/tests/cvsdiff/normalm.diff
new file mode 100644
index 00000000..935763a0
--- /dev/null
+++ b/kompare/tests/cvsdiff/normalm.diff
@@ -0,0 +1,861 @@
+Index: client/dcop.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcop.cpp,v
+retrieving revision 1.26
+diff -r1.26 dcop.cpp
+23c23,26
+< #include <qvariant.h>
+---
+> #include <ctype.h>
+> #include <stdio.h>
+> #include <stdlib.h>
+>
+25c28,39
+< #include "../kdatastream.h"
+---
+> #include <qdir.h>
+> #include <qfile.h>
+> #include <qfileinfo.h>
+> #include <qmap.h>
+> #include <qstringlist.h>
+> #include <qtextstream.h>
+> #include <qvariant.h>
+>
+> // putenv() is not available on all platforms, so make sure the emulation
+> // wrapper is available in those cases by loading config.h!
+> #include <config.h>
+>
+28,30c42
+< #include <stdlib.h>
+< #include <stdio.h>
+< #include <ctype.h>
+---
+> #include "../kdatastream.h"
+33a46,47
+> typedef QMap<QString, QString> UserList;
+>
+35a50,63
+> static QTextStream cout( stdout, IO_WriteOnly );
+> static QTextStream cerr( stderr, IO_WriteOnly );
+>
+> /**
+> * Session to send call to
+> * DefaultSession - current session. Current KDE session when called without
+> * --user or --all-users option. Otherwise this value ignores
+> * all users with more than one active session.
+> * AllSessions - Send to all sessions found. requires --user or --all-users.
+> * QuerySessions - Don't call DCOP, return a list of available sessions.
+> * CustomSession - Use the specified session
+> */
+> enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
+>
+121c149
+< void callFunction( const char* app, const char* obj, const char* func, int argc, char** args )
+---
+> void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
+123d150
+<
+139c166
+< if ( !ok && argc == 0 )
+---
+> if ( !ok && args.isEmpty() )
+156,157c183,184
+< int a = (*it).contains(',');
+< if ( ( a == 0 && argc == 0) || ( a > 0 && a + 1 == argc ) )
+---
+> uint a = (*it).contains(',');
+> if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
+164c191,192
+< exit(1);
+---
+> // exit(1);
+> return;
+246,250c274,279
+< int i = 0;
+< for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
+< marshall(arg, argc, args, i, *it);
+< }
+< if ( i != argc ) {
+---
+> uint i = 0;
+> for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
+> marshall( arg, args, i, *it );
+>
+> if ( i != args.count() )
+> {
+268a298,324
+> /**
+> * Show command-line help and exit
+> */
+> void showHelp( int exitCode = 0 )
+> {
+> cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
+> << "" << endl
+> << "Console DCOP client" << endl
+> << "" << endl
+> << "Generic options:" << endl
+> << " --help Show help about options" << endl
+> << "" << endl
+> << "Options:" << endl
+> << " --pipe Call DCOP for each line read from stdin" << endl
+> << " --user <user> Connect to the given user's DCOP server. This option will" << endl
+> << " ignore the values of the environment vars $DCOPSERVER and" << endl
+> << " $ICEAUTHORITY, even if they are set." << endl
+> << " If the user has more than one open session, you must also" << endl
+> << " use one of the --list-sessions, --session or --als-sessions" << endl
+> << " command-line options." << endl
+> << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
+> << " server. Only failed calls to existing DCOP servers will"
+> << " generate an error message. If no DCOP server is available" << endl
+> << " at all, no error will be generated." << endl;
+>
+> exit( exitCode );
+> }
+270,271c326,330
+<
+< int main( int argc, char** argv )
+---
+> /**
+> * Return a list of all users and their home directories.
+> * Returns an empty list if /etc/passwd cannot be read for some reason.
+> */
+> static UserList userList()
+272a332,340
+> UserList result;
+>
+> QFile f( "/etc/passwd" );
+>
+> if( !f.open( IO_ReadOnly ) )
+> {
+> cerr << "Can't open /etc/passwd for reading!" << endl;
+> return result;
+> }
+274,276c342,347
+< if ( argc > 1 && argv[1][0] == '-' ) {
+< fprintf( stderr, "Usage: dcop [ application [object [function [arg1] [arg2] [arg3] ... ] ] ] \n" );
+< exit(0);
+---
+> QStringList l( QStringList::split( '\n', f.readAll() ) );
+>
+> for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
+> {
+> QStringList userInfo( QStringList::split( ':', *it, true ) );
+> result[ userInfo[ 0 ] ] = userInfo[ 5 ];
+279,281c350,391
+< DCOPClient client;
+< client.attach();
+< dcop = &client;
+---
+> return result;
+> }
+>
+> /**
+> * Return a list of available DCOP sessions for the specified user
+> * An empty list means no sessions are available, or an error occurred.
+> */
+> QStringList dcopSessionList( const QString &user, const QString &home )
+> {
+> if( home.isEmpty() )
+> {
+> cerr << "WARNING: Cannot determine home directory for user "
+> << user << "!" << endl
+> << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
+> << "calling dcop." << endl;
+> return QStringList();
+> }
+>
+> QStringList result;
+> QFileInfo dirInfo( home );
+> if( !dirInfo.exists() || !dirInfo.isReadable() )
+> return result;
+>
+> QDir d( home );
+> d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
+> d.setNameFilter( ".DCOPserver*" );
+>
+> const QFileInfoList *list = d.entryInfoList();
+> if( !list )
+> return result;
+>
+> QFileInfoListIterator it( *list );
+> QFileInfo *fi;
+>
+> while ( ( fi = it.current() ) != 0 )
+> {
+> if( fi->isReadable() )
+> result.append( fi->fileName() );
+> ++it;
+> }
+> return result;
+> }
+282a393,398
+> /**
+> * Do the actual DCOP call
+> */
+> void runDCOP( QCStringList args, UserList users, Session session,
+> const QString sessionName, bool readStdin )
+> {
+286,287c402,404
+< char **args = 0;
+< if ((argc > 1) && (strncmp(argv[1], "DCOPRef(", 8)) == 0)
+---
+> QCStringList params;
+> DCOPClient *client = 0L;
+> if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
+289,304c406,429
+< char *delim = strchr(argv[1], ',');
+< if (!delim)
+< {
+< fprintf(stderr, "Error: '%s' is not a valid DCOP reference.\n", argv[1]);
+< return 1;
+< }
+< *delim = 0;
+< app = argv[1] + 8;
+< delim++;
+< delim[strlen(delim)-1] = 0;
+< objid = delim;
+< if (argc > 2)
+< function = argv[2];
+< if (argc > 3)
+< args = &argv[3];
+< argc++;
+---
+> // WARNING: This part (until the closing '}') could very
+> // well be broken now. As I don't know how to trigger and test
+> // dcoprefs this code is *not* tested. It compiles and it looks
+> // ok to me, but that's all I can say - Martijn (2001/12/24)
+> int delimPos = args[ 0 ].findRev( ',' );
+> if( delimPos == -1 )
+> {
+> cerr << "Error: '" << args[ 0 ]
+> << "' is not a valid DCOP reference." << endl;
+> exit( -1 );
+> }
+> args[ 0 ][ delimPos ] = 0;
+> app = args[ 0 ].mid( 8 );
+> delimPos++;
+> args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
+> objid = args[ 0 ].mid( delimPos );
+> if( args.count() > 1 )
+> function = args[ 1 ];
+> if( args.count() > 2 )
+> {
+> params = args;
+> params.remove( params.begin() );
+> params.remove( params.begin() );
+> }
+308,338c433,516
+< if (argc > 1)
+< app = argv[1];
+< if (argc > 2)
+< objid = argv[2];
+< if (argc > 3)
+< function = argv[3];
+< if (argc > 4)
+< args = &argv[4];
+< }
+<
+< switch ( argc ) {
+< case 0:
+< case 1:
+< queryApplications("");
+< break;
+< case 2:
+< if (endsWith(app, '*'))
+< queryApplications(app);
+< else
+< queryObjects( app, "" );
+< break;
+< case 3:
+< if (endsWith(objid, '*'))
+< queryObjects(app, objid);
+< else
+< queryFunctions( app, objid );
+< break;
+< case 4:
+< default:
+< callFunction( app, objid, function, argc - 4, args );
+< break;
+---
+> if( !args.isEmpty() )
+> app = args[ 0 ];
+> if( args.count() > 1 )
+> objid = args[ 1 ];
+> if( args.count() > 2 )
+> function = args[ 2 ];
+> if( args.count() > 3)
+> {
+> params = args;
+> params.remove( params.begin() );
+> params.remove( params.begin() );
+> params.remove( params.begin() );
+> }
+> }
+>
+> bool firstRun = true;
+> UserList::Iterator it;
+> QStringList sessions;
+> bool presetDCOPServer = false;
+> // char *dcopStr = 0L;
+> QString dcopServer;
+>
+> for( it = users.begin(); it != users.end() || firstRun; it++ )
+> {
+> firstRun = false;
+>
+> //cout << "Iterating '" << it.key() << "'" << endl;
+>
+> if( session == QuerySessions )
+> {
+> QStringList sessions = dcopSessionList( it.key(), it.data() );
+> if( sessions.isEmpty() )
+> {
+> cout << "No active sessions";
+> if( !( *it ).isEmpty() )
+> cout << " for user " << *it;
+> cout << endl;
+> }
+> else
+> {
+> cout << "Active sessions ";
+> if( !( *it ).isEmpty() )
+> cout << "for user " << *it << " ";
+> cout << ":" << endl;
+>
+> QStringList::Iterator sIt;
+> for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
+> cout << " " << *sIt << endl;
+>
+> cout << endl;
+> }
+> continue;
+> }
+>
+> if( getenv( "DCOPSERVER" ) )
+> {
+> sessions.append( getenv( "DCOPSERVER" ) );
+> presetDCOPServer = true;
+> }
+>
+> if( users.count() > 1 || ( users.count() == 1 &&
+> ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
+> {
+> sessions = dcopSessionList( it.key(), it.data() );
+> if( sessions.isEmpty() )
+> {
+> if( users.count() > 1 )
+> continue;
+> else
+> {
+> cerr << "ERROR: No active KDE sessions!" << endl
+> << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
+> << "before calling dcop." << endl;
+> exit( -1 );
+> }
+> }
+> else if( sessions.count() > 1 && session != AllSessions )
+> {
+> cerr << "ERROR: Multiple available KDE sessions!" << endl
+> << "Please specify the correct session to use with --session or use the" << endl
+> << "--all-sessions option to broadcast to all sessions." << endl;
+> exit( -1 );
+> }
+> }
+339a518,660
+> if( users.count() > 1 || ( users.count() == 1 &&
+> ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
+> {
+> // Check for ICE authority file and if the file can be read by us
+> QString home = it.data();
+> QString iceFile = it.data() + "/.ICEauthority";
+> QFileInfo fi( iceFile );
+> if( iceFile.isEmpty() )
+> {
+> cerr << "WARNING: Cannot determine home directory for user "
+> << it.key() << "!" << endl
+> << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
+> << "calling dcop." << endl;
+> }
+> else if( fi.exists() )
+> {
+> if( fi.isReadable() )
+> {
+> char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
+> putenv( envStr );
+> //cerr << "ice: " << envStr << endl;
+> }
+> else
+> {
+> cerr << "WARNING: ICE authority file " << iceFile
+> << "is not readable by you!" << endl
+> << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
+> << "calling dcop." << endl;
+> }
+> }
+> else
+> {
+> if( users.count() > 1 )
+> continue;
+> else
+> {
+> cerr << "WARNING: Cannot find ICE authority file "
+> << iceFile << "!" << endl
+> << "Please check permissions or set the $ICEAUTHORITY"
+> << " variable manually before" << endl
+> << "calling dcop." << endl;
+> }
+> }
+> }
+>
+> // Main loop
+> // If users is an empty list we're calling for the currently logged
+> // in user. In this case we don't have a session, but still want
+> // to iterate the loop once.
+> QStringList::Iterator sIt = sessions.begin();
+> for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
+> {
+> if( !presetDCOPServer && !users.isEmpty() )
+> {
+> QString dcopFile = it.data() + "/" + *sIt;
+> QFile f( dcopFile );
+> if( !f.open( IO_ReadOnly ) )
+> {
+> cerr << "Can't open " << dcopFile << " for reading!" << endl;
+> exit( -1 );
+> }
+>
+> QStringList l( QStringList::split( '\n', f.readAll() ) );
+> dcopServer = l.first();
+>
+> if( dcopServer.isEmpty() )
+> {
+> cerr << "WARNING: Unable to determine DCOP server for session "
+> << *sIt << "!" << endl
+> << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
+> << "calling dcop." << endl;
+> exit( -1 );
+> }
+> }
+>
+> delete client;
+> client = new DCOPClient;
+> if( !dcopServer.isEmpty() )
+> client->setServerAddress( dcopServer.ascii() );
+> bool success = client->attach();
+> if( !success )
+> {
+> cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
+> continue;
+> }
+> dcop = client;
+>
+> switch ( args.count() )
+> {
+> case 0:
+> queryApplications("");
+> break;
+> case 1:
+> if (endsWith(app, '*'))
+> queryApplications(app);
+> else
+> queryObjects( app, "" );
+> break;
+> case 2:
+> if (endsWith(objid, '*'))
+> queryObjects(app, objid);
+> else
+> queryFunctions( app, objid );
+> break;
+> case 3:
+> default:
+> if( readStdin )
+> {
+> QCStringList::Iterator replaceArg = args.end();
+>
+> QCStringList::Iterator it;
+> for( it = args.begin(); it != args.end(); it++ )
+> if( *it == "%1" )
+> replaceArg = it;
+>
+> // Read from stdin until EOF and call function for each line read
+> char *buf = new char[ 1000 ];
+> while ( !feof( stdin ) )
+> {
+> fgets( buf, 1000, stdin );
+>
+> if( replaceArg != args.end() )
+> *replaceArg = buf;
+>
+> callFunction( app, objid, function, params );
+> }
+> }
+> else
+> {
+> // Just call function
+> // cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
+> callFunction( app, objid, function, params );
+> }
+> break;
+> }
+> // Another sIt++ would make the loop infinite...
+> if( users.isEmpty() )
+> break;
+> }
+>
+> // Another it++ would make the loop infinite...
+> if( it == users.end() )
+> break;
+340a662,767
+> }
+>
+>
+> int main( int argc, char** argv )
+> {
+> bool readStdin = false;
+> int numOptions = 0;
+> QString user;
+> Session session = DefaultSession;
+> QString sessionName;
+>
+> // Scan for command-line options first
+> for( int pos = 1 ; pos <= argc - 1 ; pos++ )
+> {
+> if( strcmp( argv[ pos ], "--help" ) == 0 )
+> showHelp( 0 );
+> else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
+> {
+> readStdin = true;
+> numOptions++;
+> }
+> else if( strcmp( argv[ pos ], "--user" ) == 0 )
+> {
+> if( pos <= argc - 2 )
+> {
+> user = QString::fromLocal8Bit( argv[ pos + 1] );
+> numOptions +=2;
+> pos++;
+> }
+> else
+> {
+> cerr << "Missing username for '--user' option!" << endl << endl;
+> showHelp( -1 );
+> }
+> }
+> else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
+> {
+> user = "*";
+> numOptions ++;
+> }
+> else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
+> {
+> session = QuerySessions;
+> numOptions ++;
+> }
+> else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
+> {
+> session = AllSessions;
+> numOptions ++;
+> }
+> else if( argv[ pos ][ 0 ] == '-' )
+> {
+> cerr << "Unknown command-line option '" << argv[ pos ]
+> << "'." << endl << endl;
+> showHelp( -1 );
+> }
+> else
+> break; // End of options
+> }
+>
+> argc -= numOptions;
+>
+> QCStringList args;
+> for( int i = numOptions; i < argc + numOptions - 1; i++ )
+> args.append( argv[ i + 1 ] );
+>
+> if( readStdin && args.count() < 3 )
+> {
+> cerr << "--pipe option only supported for function calls!" << endl << endl;
+> showHelp( -1 );
+> }
+>
+> if( user == "*" && args.count() < 3 && session != QuerySessions )
+> {
+> cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
+> showHelp( -1 );
+> }
+>
+> if( session == QuerySessions && !args.isEmpty() )
+> {
+> cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
+> showHelp( -1 );
+> }
+>
+> if( session == QuerySessions && user.isEmpty() )
+> {
+> cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
+> << "--all-users options!" << endl << endl;
+> showHelp( -1 );
+> }
+>
+> if( session != DefaultSession && session != QuerySessions &&
+> args.count() < 3 )
+> {
+> cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
+> << "calls!" << endl << endl;
+> showHelp( -1 );
+> }
+>
+> UserList users;
+> if( user == "*" )
+> users = userList();
+> else if( !user.isEmpty() )
+> users[ user ] = userList()[ user ];
+>
+> runDCOP( args, users, session, sessionName, readStdin );
+343a771,773
+>
+> // vim: set ts=8 sts=4 sw=4 noet:
+>
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -r1.2 dcopfind.cpp
+39c39
+< bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
+---
+> bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+121c121
+< if ( (int) types.count() != argc ) {
+---
+> if ( types.count() != args.count() ) {
+131c131
+< marshall(arg, argc, args, i, *it);
+---
+> marshall(arg, args, i, *it);
+133c133
+< if ( (int) i != argc ) {
+---
+> if ( (uint) i != args.count() ) {
+224c224,228
+< findObject( app, objid, function, argc, args );
+---
+> QCStringList params;
+> for( int i = 0; i < argc; i++ )
+> params.append( args[ i ] );
+>
+> findObject( app, objid, function, params );
+Index: client/marshall.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/marshall.cpp,v
+retrieving revision 1.3
+diff -r1.3 marshall.cpp
+245c245
+< void marshall(QDataStream &arg, int argc, char **argv, int &i, QString type)
+---
+> void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
+247,317c247,256
+< if (type == "QStringList")
+< type = "QValueList<QString>";
+< if (type == "QCStringList")
+< type = "QValueList<QCString>";
+< if (i >= argc)
+< {
+< qWarning("Not enough arguments.");
+< exit(1);
+< }
+< QString s = QString::fromLocal8Bit(argv[i]);
+<
+< if ( type == "int" )
+< arg << s.toInt();
+< else if ( type == "uint" )
+< arg << s.toUInt();
+< else if ( type == "unsigned" )
+< arg << s.toUInt();
+< else if ( type == "unsigned int" )
+< arg << s.toUInt();
+< else if ( type == "long" )
+< arg << s.toLong();
+< else if ( type == "long int" )
+< arg << s.toLong();
+< else if ( type == "unsigned long" )
+< arg << s.toULong();
+< else if ( type == "unsigned long int" )
+< arg << s.toULong();
+< else if ( type == "float" )
+< arg << s.toFloat();
+< else if ( type == "double" )
+< arg << s.toDouble();
+< else if ( type == "bool" )
+< arg << mkBool( s );
+< else if ( type == "QString" )
+< arg << s;
+< else if ( type == "QCString" )
+< arg << QCString( argv[i] );
+< else if ( type == "QColor" )
+< arg << mkColor( s );
+< else if ( type == "QPoint" )
+< arg << mkPoint( s );
+< else if ( type == "QSize" )
+< arg << mkSize( s );
+< else if ( type == "QRect" )
+< arg << mkRect( s );
+< else if ( type == "QVariant" ) {
+< if ( s == "true" || s == "false" )
+< arg << QVariant( mkBool( s ), 42 );
+< else if ( s.left( 4 ) == "int(" )
+< arg << QVariant( s.mid(4, s.length()-5).toInt() );
+< else if ( s.left( 7 ) == "QPoint(" )
+< arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
+< else if ( s.left( 6 ) == "QSize(" )
+< arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
+< else if ( s.left( 6 ) == "QRect(" )
+< arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
+< else if ( s.left( 7 ) == "QColor(" )
+< arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
+< else
+< arg << QVariant( s );
+< } else if ( type.startsWith("QValueList<")) {
+< type = type.mid(11, type.length() - 12);
+< QStringList list;
+< QString delim = s;
+< if (delim == "[")
+< delim = "]";
+< if (delim == "(")
+< delim = ")";
+< i++;
+< QByteArray dummy_data;
+< QDataStream dummy_arg(dummy_data, IO_WriteOnly);
+---
+> if (type == "QStringList")
+> type = "QValueList<QString>";
+> if (type == "QCStringList")
+> type = "QValueList<QCString>";
+> if( i > args.count() )
+> {
+> qWarning("Not enough arguments.");
+> exit(1);
+> }
+> QString s = QString::fromLocal8Bit( args[ i ] );
+319,346c258,314
+< int j = i;
+< int count = 0;
+< // Parse list to get the count
+< while (true) {
+< if (j >= argc)
+< {
+< qWarning("List end-delimiter '%s' not found.", delim.latin1());
+< exit(1);
+< }
+< if (argv[j] == delim) break;
+< marshall(dummy_arg, argc, argv, j, type);
+< count++;
+< }
+< arg << (Q_UINT32) count;
+< // Parse the list for real
+< while (true) {
+< if (i >= argc)
+< {
+< qWarning("List end-delimiter '%s' not found.", delim.latin1());
+< exit(1);
+< }
+< if (argv[i] == delim) break;
+< marshall(arg, argc, argv, i, type);
+< }
+< } else {
+< qWarning( "cannot handle datatype '%s'", type.latin1() );
+< exit(1);
+< }
+---
+> if ( type == "int" )
+> arg << s.toInt();
+> else if ( type == "uint" )
+> arg << s.toUInt();
+> else if ( type == "unsigned" )
+> arg << s.toUInt();
+> else if ( type == "unsigned int" )
+> arg << s.toUInt();
+> else if ( type == "long" )
+> arg << s.toLong();
+> else if ( type == "long int" )
+> arg << s.toLong();
+> else if ( type == "unsigned long" )
+> arg << s.toULong();
+> else if ( type == "unsigned long int" )
+> arg << s.toULong();
+> else if ( type == "float" )
+> arg << s.toFloat();
+> else if ( type == "double" )
+> arg << s.toDouble();
+> else if ( type == "bool" )
+> arg << mkBool( s );
+> else if ( type == "QString" )
+> arg << s;
+> else if ( type == "QCString" )
+> arg << QCString( args[ i ] );
+> else if ( type == "QColor" )
+> arg << mkColor( s );
+> else if ( type == "QPoint" )
+> arg << mkPoint( s );
+> else if ( type == "QSize" )
+> arg << mkSize( s );
+> else if ( type == "QRect" )
+> arg << mkRect( s );
+> else if ( type == "QVariant" ) {
+> if ( s == "true" || s == "false" )
+> arg << QVariant( mkBool( s ), 42 );
+> else if ( s.left( 4 ) == "int(" )
+> arg << QVariant( s.mid(4, s.length()-5).toInt() );
+> else if ( s.left( 7 ) == "QPoint(" )
+> arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
+> else if ( s.left( 6 ) == "QSize(" )
+> arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
+> else if ( s.left( 6 ) == "QRect(" )
+> arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
+> else if ( s.left( 7 ) == "QColor(" )
+> arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
+> else
+> arg << QVariant( s );
+> } else if ( type.startsWith("QValueList<")) {
+> type = type.mid(11, type.length() - 12);
+> QStringList list;
+> QString delim = s;
+> if (delim == "[")
+> delim = "]";
+> if (delim == "(")
+> delim = ")";
+347a316,349
+> QByteArray dummy_data;
+> QDataStream dummy_arg(dummy_data, IO_WriteOnly);
+>
+> uint j = i;
+> uint count = 0;
+> // Parse list to get the count
+> while (true) {
+> if( j > args.count() )
+> {
+> qWarning("List end-delimiter '%s' not found.", delim.latin1());
+> exit(1);
+> }
+> if( QString::fromLocal8Bit( args[ j ] ) == delim )
+> break;
+> marshall( dummy_arg, args, j, type );
+> count++;
+> }
+> arg << (Q_UINT32) count;
+> // Parse the list for real
+> while (true) {
+> if( i > args.count() )
+> {
+> qWarning("List end-delimiter '%s' not found.", delim.latin1());
+> exit(1);
+> }
+> if( QString::fromLocal8Bit( args[ i ] ) == delim )
+> break;
+> marshall( arg, args, i, type );
+> }
+> } else {
+> qWarning( "cannot handle datatype '%s'", type.latin1() );
+> exit(1);
+> }
+> i++;
diff --git a/kompare/tests/cvsdiff/rcs.diff b/kompare/tests/cvsdiff/rcs.diff
new file mode 100644
index 00000000..da42d91a
--- /dev/null
+++ b/kompare/tests/cvsdiff/rcs.diff
@@ -0,0 +1,24 @@
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -n -r1.2 dcopfind.cpp
+d39 1
+a39 1
+bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+d121 1
+a121 1
+ if ( types.count() != args.count() ) {
+d131 1
+a131 1
+ marshall(arg, args, i, *it);
+d133 1
+a133 1
+ if ( (uint) i != args.count() ) {
+d224 1
+a224 5
+ QCStringList params;
+ for( int i = 0; i < argc; i++ )
+ params.append( args[ i ] );
+
+ findObject( app, objid, function, params );
diff --git a/kompare/tests/cvsdiff/rcsm.diff b/kompare/tests/cvsdiff/rcsm.diff
new file mode 100644
index 00000000..c690b2a7
--- /dev/null
+++ b/kompare/tests/cvsdiff/rcsm.diff
@@ -0,0 +1,683 @@
+Index: client/dcop.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcop.cpp,v
+retrieving revision 1.26
+diff -n -r1.26 dcop.cpp
+d23 1
+a23 4
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+d25 1
+a25 12
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qmap.h>
+#include <qstringlist.h>
+#include <qtextstream.h>
+#include <qvariant.h>
+
+// putenv() is not available on all platforms, so make sure the emulation
+// wrapper is available in those cases by loading config.h!
+#include <config.h>
+
+d28 3
+a30 1
+#include "../kdatastream.h"
+a33 2
+typedef QMap<QString, QString> UserList;
+
+a35 14
+static QTextStream cout( stdout, IO_WriteOnly );
+static QTextStream cerr( stderr, IO_WriteOnly );
+
+/**
+ * Session to send call to
+ * DefaultSession - current session. Current KDE session when called without
+ * --user or --all-users option. Otherwise this value ignores
+ * all users with more than one active session.
+ * AllSessions - Send to all sessions found. requires --user or --all-users.
+ * QuerySessions - Don't call DCOP, return a list of available sessions.
+ * CustomSession - Use the specified session
+ */
+enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
+
+d121 1
+a121 1
+void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
+d123 1
+d139 1
+a139 1
+ if ( !ok && args.isEmpty() )
+d156 2
+a157 2
+ uint a = (*it).contains(',');
+ if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
+d164 1
+a164 2
+// exit(1);
+ return;
+d246 5
+a250 6
+ uint i = 0;
+ for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
+ marshall( arg, args, i, *it );
+
+ if ( i != args.count() )
+ {
+a268 27
+/**
+ * Show command-line help and exit
+ */
+void showHelp( int exitCode = 0 )
+{
+ cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
+ << "" << endl
+ << "Console DCOP client" << endl
+ << "" << endl
+ << "Generic options:" << endl
+ << " --help Show help about options" << endl
+ << "" << endl
+ << "Options:" << endl
+ << " --pipe Call DCOP for each line read from stdin" << endl
+ << " --user <user> Connect to the given user's DCOP server. This option will" << endl
+ << " ignore the values of the environment vars $DCOPSERVER and" << endl
+ << " $ICEAUTHORITY, even if they are set." << endl
+ << " If the user has more than one open session, you must also" << endl
+ << " use one of the --list-sessions, --session or --als-sessions" << endl
+ << " command-line options." << endl
+ << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
+ << " server. Only failed calls to existing DCOP servers will"
+ << " generate an error message. If no DCOP server is available" << endl
+ << " at all, no error will be generated." << endl;
+
+ exit( exitCode );
+}
+d270 2
+a271 5
+/**
+ * Return a list of all users and their home directories.
+ * Returns an empty list if /etc/passwd cannot be read for some reason.
+ */
+static UserList userList()
+a272 9
+ UserList result;
+
+ QFile f( "/etc/passwd" );
+
+ if( !f.open( IO_ReadOnly ) )
+ {
+ cerr << "Can't open /etc/passwd for reading!" << endl;
+ return result;
+ }
+d274 3
+a276 6
+ QStringList l( QStringList::split( '\n', f.readAll() ) );
+
+ for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
+ {
+ QStringList userInfo( QStringList::split( ':', *it, true ) );
+ result[ userInfo[ 0 ] ] = userInfo[ 5 ];
+d279 3
+a281 42
+ return result;
+}
+
+/**
+ * Return a list of available DCOP sessions for the specified user
+ * An empty list means no sessions are available, or an error occurred.
+ */
+QStringList dcopSessionList( const QString &user, const QString &home )
+{
+ if( home.isEmpty() )
+ {
+ cerr << "WARNING: Cannot determine home directory for user "
+ << user << "!" << endl
+ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
+ << "calling dcop." << endl;
+ return QStringList();
+ }
+
+ QStringList result;
+ QFileInfo dirInfo( home );
+ if( !dirInfo.exists() || !dirInfo.isReadable() )
+ return result;
+
+ QDir d( home );
+ d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
+ d.setNameFilter( ".DCOPserver*" );
+
+ const QFileInfoList *list = d.entryInfoList();
+ if( !list )
+ return result;
+
+ QFileInfoListIterator it( *list );
+ QFileInfo *fi;
+
+ while ( ( fi = it.current() ) != 0 )
+ {
+ if( fi->isReadable() )
+ result.append( fi->fileName() );
+ ++it;
+ }
+ return result;
+}
+a282 6
+/**
+ * Do the actual DCOP call
+ */
+void runDCOP( QCStringList args, UserList users, Session session,
+ const QString sessionName, bool readStdin )
+{
+d286 2
+a287 3
+ QCStringList params;
+ DCOPClient *client = 0L;
+ if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
+d289 16
+a304 24
+ // WARNING: This part (until the closing '}') could very
+ // well be broken now. As I don't know how to trigger and test
+ // dcoprefs this code is *not* tested. It compiles and it looks
+ // ok to me, but that's all I can say - Martijn (2001/12/24)
+ int delimPos = args[ 0 ].findRev( ',' );
+ if( delimPos == -1 )
+ {
+ cerr << "Error: '" << args[ 0 ]
+ << "' is not a valid DCOP reference." << endl;
+ exit( -1 );
+ }
+ args[ 0 ][ delimPos ] = 0;
+ app = args[ 0 ].mid( 8 );
+ delimPos++;
+ args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
+ objid = args[ 0 ].mid( delimPos );
+ if( args.count() > 1 )
+ function = args[ 1 ];
+ if( args.count() > 2 )
+ {
+ params = args;
+ params.remove( params.begin() );
+ params.remove( params.begin() );
+ }
+d308 31
+a338 84
+ if( !args.isEmpty() )
+ app = args[ 0 ];
+ if( args.count() > 1 )
+ objid = args[ 1 ];
+ if( args.count() > 2 )
+ function = args[ 2 ];
+ if( args.count() > 3)
+ {
+ params = args;
+ params.remove( params.begin() );
+ params.remove( params.begin() );
+ params.remove( params.begin() );
+ }
+ }
+
+ bool firstRun = true;
+ UserList::Iterator it;
+ QStringList sessions;
+ bool presetDCOPServer = false;
+// char *dcopStr = 0L;
+ QString dcopServer;
+
+ for( it = users.begin(); it != users.end() || firstRun; it++ )
+ {
+ firstRun = false;
+
+ //cout << "Iterating '" << it.key() << "'" << endl;
+
+ if( session == QuerySessions )
+ {
+ QStringList sessions = dcopSessionList( it.key(), it.data() );
+ if( sessions.isEmpty() )
+ {
+ cout << "No active sessions";
+ if( !( *it ).isEmpty() )
+ cout << " for user " << *it;
+ cout << endl;
+ }
+ else
+ {
+ cout << "Active sessions ";
+ if( !( *it ).isEmpty() )
+ cout << "for user " << *it << " ";
+ cout << ":" << endl;
+
+ QStringList::Iterator sIt;
+ for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
+ cout << " " << *sIt << endl;
+
+ cout << endl;
+ }
+ continue;
+ }
+
+ if( getenv( "DCOPSERVER" ) )
+ {
+ sessions.append( getenv( "DCOPSERVER" ) );
+ presetDCOPServer = true;
+ }
+
+ if( users.count() > 1 || ( users.count() == 1 &&
+ ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
+ {
+ sessions = dcopSessionList( it.key(), it.data() );
+ if( sessions.isEmpty() )
+ {
+ if( users.count() > 1 )
+ continue;
+ else
+ {
+ cerr << "ERROR: No active KDE sessions!" << endl
+ << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
+ << "before calling dcop." << endl;
+ exit( -1 );
+ }
+ }
+ else if( sessions.count() > 1 && session != AllSessions )
+ {
+ cerr << "ERROR: Multiple available KDE sessions!" << endl
+ << "Please specify the correct session to use with --session or use the" << endl
+ << "--all-sessions option to broadcast to all sessions." << endl;
+ exit( -1 );
+ }
+ }
+a339 143
+ if( users.count() > 1 || ( users.count() == 1 &&
+ ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
+ {
+ // Check for ICE authority file and if the file can be read by us
+ QString home = it.data();
+ QString iceFile = it.data() + "/.ICEauthority";
+ QFileInfo fi( iceFile );
+ if( iceFile.isEmpty() )
+ {
+ cerr << "WARNING: Cannot determine home directory for user "
+ << it.key() << "!" << endl
+ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
+ << "calling dcop." << endl;
+ }
+ else if( fi.exists() )
+ {
+ if( fi.isReadable() )
+ {
+ char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
+ putenv( envStr );
+ //cerr << "ice: " << envStr << endl;
+ }
+ else
+ {
+ cerr << "WARNING: ICE authority file " << iceFile
+ << "is not readable by you!" << endl
+ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
+ << "calling dcop." << endl;
+ }
+ }
+ else
+ {
+ if( users.count() > 1 )
+ continue;
+ else
+ {
+ cerr << "WARNING: Cannot find ICE authority file "
+ << iceFile << "!" << endl
+ << "Please check permissions or set the $ICEAUTHORITY"
+ << " variable manually before" << endl
+ << "calling dcop." << endl;
+ }
+ }
+ }
+
+ // Main loop
+ // If users is an empty list we're calling for the currently logged
+ // in user. In this case we don't have a session, but still want
+ // to iterate the loop once.
+ QStringList::Iterator sIt = sessions.begin();
+ for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
+ {
+ if( !presetDCOPServer && !users.isEmpty() )
+ {
+ QString dcopFile = it.data() + "/" + *sIt;
+ QFile f( dcopFile );
+ if( !f.open( IO_ReadOnly ) )
+ {
+ cerr << "Can't open " << dcopFile << " for reading!" << endl;
+ exit( -1 );
+ }
+
+ QStringList l( QStringList::split( '\n', f.readAll() ) );
+ dcopServer = l.first();
+
+ if( dcopServer.isEmpty() )
+ {
+ cerr << "WARNING: Unable to determine DCOP server for session "
+ << *sIt << "!" << endl
+ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
+ << "calling dcop." << endl;
+ exit( -1 );
+ }
+ }
+
+ delete client;
+ client = new DCOPClient;
+ if( !dcopServer.isEmpty() )
+ client->setServerAddress( dcopServer.ascii() );
+ bool success = client->attach();
+ if( !success )
+ {
+ cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
+ continue;
+ }
+ dcop = client;
+
+ switch ( args.count() )
+ {
+ case 0:
+ queryApplications("");
+ break;
+ case 1:
+ if (endsWith(app, '*'))
+ queryApplications(app);
+ else
+ queryObjects( app, "" );
+ break;
+ case 2:
+ if (endsWith(objid, '*'))
+ queryObjects(app, objid);
+ else
+ queryFunctions( app, objid );
+ break;
+ case 3:
+ default:
+ if( readStdin )
+ {
+ QCStringList::Iterator replaceArg = args.end();
+
+ QCStringList::Iterator it;
+ for( it = args.begin(); it != args.end(); it++ )
+ if( *it == "%1" )
+ replaceArg = it;
+
+ // Read from stdin until EOF and call function for each line read
+ char *buf = new char[ 1000 ];
+ while ( !feof( stdin ) )
+ {
+ fgets( buf, 1000, stdin );
+
+ if( replaceArg != args.end() )
+ *replaceArg = buf;
+
+ callFunction( app, objid, function, params );
+ }
+ }
+ else
+ {
+ // Just call function
+// cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
+ callFunction( app, objid, function, params );
+ }
+ break;
+ }
+ // Another sIt++ would make the loop infinite...
+ if( users.isEmpty() )
+ break;
+ }
+
+ // Another it++ would make the loop infinite...
+ if( it == users.end() )
+ break;
+a340 106
+}
+
+
+int main( int argc, char** argv )
+{
+ bool readStdin = false;
+ int numOptions = 0;
+ QString user;
+ Session session = DefaultSession;
+ QString sessionName;
+
+ // Scan for command-line options first
+ for( int pos = 1 ; pos <= argc - 1 ; pos++ )
+ {
+ if( strcmp( argv[ pos ], "--help" ) == 0 )
+ showHelp( 0 );
+ else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
+ {
+ readStdin = true;
+ numOptions++;
+ }
+ else if( strcmp( argv[ pos ], "--user" ) == 0 )
+ {
+ if( pos <= argc - 2 )
+ {
+ user = QString::fromLocal8Bit( argv[ pos + 1] );
+ numOptions +=2;
+ pos++;
+ }
+ else
+ {
+ cerr << "Missing username for '--user' option!" << endl << endl;
+ showHelp( -1 );
+ }
+ }
+ else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
+ {
+ user = "*";
+ numOptions ++;
+ }
+ else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
+ {
+ session = QuerySessions;
+ numOptions ++;
+ }
+ else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
+ {
+ session = AllSessions;
+ numOptions ++;
+ }
+ else if( argv[ pos ][ 0 ] == '-' )
+ {
+ cerr << "Unknown command-line option '" << argv[ pos ]
+ << "'." << endl << endl;
+ showHelp( -1 );
+ }
+ else
+ break; // End of options
+ }
+
+ argc -= numOptions;
+
+ QCStringList args;
+ for( int i = numOptions; i < argc + numOptions - 1; i++ )
+ args.append( argv[ i + 1 ] );
+
+ if( readStdin && args.count() < 3 )
+ {
+ cerr << "--pipe option only supported for function calls!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ if( user == "*" && args.count() < 3 && session != QuerySessions )
+ {
+ cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ if( session == QuerySessions && !args.isEmpty() )
+ {
+ cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ if( session == QuerySessions && user.isEmpty() )
+ {
+ cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
+ << "--all-users options!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ if( session != DefaultSession && session != QuerySessions &&
+ args.count() < 3 )
+ {
+ cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
+ << "calls!" << endl << endl;
+ showHelp( -1 );
+ }
+
+ UserList users;
+ if( user == "*" )
+ users = userList();
+ else if( !user.isEmpty() )
+ users[ user ] = userList()[ user ];
+
+ runDCOP( args, users, session, sessionName, readStdin );
+a343 3
+
+// vim: set ts=8 sts=4 sw=4 noet:
+
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -n -r1.2 dcopfind.cpp
+d39 1
+a39 1
+bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+d121 1
+a121 1
+ if ( types.count() != args.count() ) {
+d131 1
+a131 1
+ marshall(arg, args, i, *it);
+d133 1
+a133 1
+ if ( (uint) i != args.count() ) {
+d224 1
+a224 5
+ QCStringList params;
+ for( int i = 0; i < argc; i++ )
+ params.append( args[ i ] );
+
+ findObject( app, objid, function, params );
+Index: client/marshall.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/marshall.cpp,v
+retrieving revision 1.3
+diff -n -r1.3 marshall.cpp
+d245 1
+a245 1
+void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
+d247 71
+a317 10
+ if (type == "QStringList")
+ type = "QValueList<QString>";
+ if (type == "QCStringList")
+ type = "QValueList<QCString>";
+ if( i > args.count() )
+ {
+ qWarning("Not enough arguments.");
+ exit(1);
+ }
+ QString s = QString::fromLocal8Bit( args[ i ] );
+d319 28
+a346 57
+ if ( type == "int" )
+ arg << s.toInt();
+ else if ( type == "uint" )
+ arg << s.toUInt();
+ else if ( type == "unsigned" )
+ arg << s.toUInt();
+ else if ( type == "unsigned int" )
+ arg << s.toUInt();
+ else if ( type == "long" )
+ arg << s.toLong();
+ else if ( type == "long int" )
+ arg << s.toLong();
+ else if ( type == "unsigned long" )
+ arg << s.toULong();
+ else if ( type == "unsigned long int" )
+ arg << s.toULong();
+ else if ( type == "float" )
+ arg << s.toFloat();
+ else if ( type == "double" )
+ arg << s.toDouble();
+ else if ( type == "bool" )
+ arg << mkBool( s );
+ else if ( type == "QString" )
+ arg << s;
+ else if ( type == "QCString" )
+ arg << QCString( args[ i ] );
+ else if ( type == "QColor" )
+ arg << mkColor( s );
+ else if ( type == "QPoint" )
+ arg << mkPoint( s );
+ else if ( type == "QSize" )
+ arg << mkSize( s );
+ else if ( type == "QRect" )
+ arg << mkRect( s );
+ else if ( type == "QVariant" ) {
+ if ( s == "true" || s == "false" )
+ arg << QVariant( mkBool( s ), 42 );
+ else if ( s.left( 4 ) == "int(" )
+ arg << QVariant( s.mid(4, s.length()-5).toInt() );
+ else if ( s.left( 7 ) == "QPoint(" )
+ arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
+ else if ( s.left( 6 ) == "QSize(" )
+ arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
+ else if ( s.left( 6 ) == "QRect(" )
+ arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
+ else if ( s.left( 7 ) == "QColor(" )
+ arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
+ else
+ arg << QVariant( s );
+ } else if ( type.startsWith("QValueList<")) {
+ type = type.mid(11, type.length() - 12);
+ QStringList list;
+ QString delim = s;
+ if (delim == "[")
+ delim = "]";
+ if (delim == "(")
+ delim = ")";
+a347 34
+ QByteArray dummy_data;
+ QDataStream dummy_arg(dummy_data, IO_WriteOnly);
+
+ uint j = i;
+ uint count = 0;
+ // Parse list to get the count
+ while (true) {
+ if( j > args.count() )
+ {
+ qWarning("List end-delimiter '%s' not found.", delim.latin1());
+ exit(1);
+ }
+ if( QString::fromLocal8Bit( args[ j ] ) == delim )
+ break;
+ marshall( dummy_arg, args, j, type );
+ count++;
+ }
+ arg << (Q_UINT32) count;
+ // Parse the list for real
+ while (true) {
+ if( i > args.count() )
+ {
+ qWarning("List end-delimiter '%s' not found.", delim.latin1());
+ exit(1);
+ }
+ if( QString::fromLocal8Bit( args[ i ] ) == delim )
+ break;
+ marshall( arg, args, i, type );
+ }
+ } else {
+ qWarning( "cannot handle datatype '%s'", type.latin1() );
+ exit(1);
+ }
+ i++;
diff --git a/kompare/tests/cvsdiff/unified.diff b/kompare/tests/cvsdiff/unified.diff
new file mode 100644
index 00000000..562dee43
--- /dev/null
+++ b/kompare/tests/cvsdiff/unified.diff
@@ -0,0 +1,50 @@
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -u -r1.2 dcopfind.cpp
+--- client/dcopfind.cpp 2001/10/31 01:17:39 1.2
++++ client/dcopfind.cpp 2002/01/16 18:07:51
+@@ -36,7 +36,7 @@
+ static bool bAppIdOnly = 0;
+ static bool bLaunchApp = 0;
+
+-bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
++bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+ {
+ QString f = func; // Qt is better with unicode strings, so use one.
+ int left = f.find( '(' );
+@@ -118,7 +118,7 @@
+ f = fc;
+ }
+
+- if ( (int) types.count() != argc ) {
++ if ( types.count() != args.count() ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+@@ -128,9 +128,9 @@
+
+ int i = 0;
+ for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
+- marshall(arg, argc, args, i, *it);
++ marshall(arg, args, i, *it);
+ }
+- if ( (int) i != argc ) {
++ if ( (uint) i != args.count() ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+@@ -221,7 +221,11 @@
+ argc = 0;
+ }
+
+- findObject( app, objid, function, argc, args );
++ QCStringList params;
++ for( int i = 0; i < argc; i++ )
++ params.append( args[ i ] );
++
++ findObject( app, objid, function, params );
+
+ return 0;
+ }
diff --git a/kompare/tests/cvsdiff/unifiedm.diff b/kompare/tests/cvsdiff/unifiedm.diff
new file mode 100644
index 00000000..1de79f8f
--- /dev/null
+++ b/kompare/tests/cvsdiff/unifiedm.diff
@@ -0,0 +1,924 @@
+Index: client/dcop.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcop.cpp,v
+retrieving revision 1.26
+diff -u -r1.26 dcop.cpp
+--- client/dcop.cpp 2001/10/31 01:17:39 1.26
++++ client/dcop.cpp 2002/01/16 18:06:14
+@@ -20,19 +20,47 @@
+
+ ******************************************************************/
+
+-#include <qvariant.h>
++#include <ctype.h>
++#include <stdio.h>
++#include <stdlib.h>
++
+ #include <qcolor.h>
+-#include "../kdatastream.h"
++#include <qdir.h>
++#include <qfile.h>
++#include <qfileinfo.h>
++#include <qmap.h>
++#include <qstringlist.h>
++#include <qtextstream.h>
++#include <qvariant.h>
++
++// putenv() is not available on all platforms, so make sure the emulation
++// wrapper is available in those cases by loading config.h!
++#include <config.h>
++
+ #include "../dcopclient.h"
+ #include "../dcopref.h"
+-#include <stdlib.h>
+-#include <stdio.h>
+-#include <ctype.h>
++#include "../kdatastream.h"
+
+ #include "marshall.cpp"
+
++typedef QMap<QString, QString> UserList;
++
+ static DCOPClient* dcop = 0;
+
++static QTextStream cout( stdout, IO_WriteOnly );
++static QTextStream cerr( stderr, IO_WriteOnly );
++
++/**
++ * Session to send call to
++ * DefaultSession - current session. Current KDE session when called without
++ * --user or --all-users option. Otherwise this value ignores
++ * all users with more than one active session.
++ * AllSessions - Send to all sessions found. requires --user or --all-users.
++ * QuerySessions - Don't call DCOP, return a list of available sessions.
++ * CustomSession - Use the specified session
++ */
++enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
++
+ bool startsWith(const QCString &id, const char *str, int n)
+ {
+ return !n || (strncmp(id.data(), str, n) == 0);
+@@ -118,9 +146,8 @@
+ }
+ }
+
+-void callFunction( const char* app, const char* obj, const char* func, int argc, char** args )
++void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
+ {
+-
+ QString f = func; // Qt is better with unicode strings, so use one.
+ int left = f.find( '(' );
+ int right = f.find( ')' );
+@@ -136,7 +163,7 @@
+ bool ok = false;
+ QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
+ QCString realfunc;
+- if ( !ok && argc == 0 )
++ if ( !ok && args.isEmpty() )
+ goto doit;
+ if ( !ok )
+ {
+@@ -153,15 +180,16 @@
+
+ if ( l > 0 && (*it).mid( s, l - s ) == func ) {
+ realfunc = (*it).mid( s );
+- int a = (*it).contains(',');
+- if ( ( a == 0 && argc == 0) || ( a > 0 && a + 1 == argc ) )
++ uint a = (*it).contains(',');
++ if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
+ break;
+ }
+ }
+ if ( realfunc.isEmpty() )
+ {
+ qWarning("no such function");
+- exit(1);
++// exit(1);
++ return;
+ }
+ f = realfunc;
+ left = f.find( '(' );
+@@ -243,11 +271,12 @@
+ QCString replyType;
+ QDataStream arg(data, IO_WriteOnly);
+
+- int i = 0;
+- for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
+- marshall(arg, argc, args, i, *it);
+- }
+- if ( i != argc ) {
++ uint i = 0;
++ for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
++ marshall( arg, args, i, *it );
++
++ if ( i != args.count() )
++ {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+@@ -265,79 +294,480 @@
+ }
+ }
+ }
+-
+
++/**
++ * Show command-line help and exit
++ */
++void showHelp( int exitCode = 0 )
++{
++ cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
++ << "" << endl
++ << "Console DCOP client" << endl
++ << "" << endl
++ << "Generic options:" << endl
++ << " --help Show help about options" << endl
++ << "" << endl
++ << "Options:" << endl
++ << " --pipe Call DCOP for each line read from stdin" << endl
++ << " --user <user> Connect to the given user's DCOP server. This option will" << endl
++ << " ignore the values of the environment vars $DCOPSERVER and" << endl
++ << " $ICEAUTHORITY, even if they are set." << endl
++ << " If the user has more than one open session, you must also" << endl
++ << " use one of the --list-sessions, --session or --als-sessions" << endl
++ << " command-line options." << endl
++ << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
++ << " server. Only failed calls to existing DCOP servers will"
++ << " generate an error message. If no DCOP server is available" << endl
++ << " at all, no error will be generated." << endl;
++
++ exit( exitCode );
++}
+
+-int main( int argc, char** argv )
++/**
++ * Return a list of all users and their home directories.
++ * Returns an empty list if /etc/passwd cannot be read for some reason.
++ */
++static UserList userList()
+ {
++ UserList result;
++
++ QFile f( "/etc/passwd" );
++
++ if( !f.open( IO_ReadOnly ) )
++ {
++ cerr << "Can't open /etc/passwd for reading!" << endl;
++ return result;
++ }
+
+- if ( argc > 1 && argv[1][0] == '-' ) {
+- fprintf( stderr, "Usage: dcop [ application [object [function [arg1] [arg2] [arg3] ... ] ] ] \n" );
+- exit(0);
++ QStringList l( QStringList::split( '\n', f.readAll() ) );
++
++ for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
++ {
++ QStringList userInfo( QStringList::split( ':', *it, true ) );
++ result[ userInfo[ 0 ] ] = userInfo[ 5 ];
+ }
+
+- DCOPClient client;
+- client.attach();
+- dcop = &client;
++ return result;
++}
++
++/**
++ * Return a list of available DCOP sessions for the specified user
++ * An empty list means no sessions are available, or an error occurred.
++ */
++QStringList dcopSessionList( const QString &user, const QString &home )
++{
++ if( home.isEmpty() )
++ {
++ cerr << "WARNING: Cannot determine home directory for user "
++ << user << "!" << endl
++ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
++ << "calling dcop." << endl;
++ return QStringList();
++ }
++
++ QStringList result;
++ QFileInfo dirInfo( home );
++ if( !dirInfo.exists() || !dirInfo.isReadable() )
++ return result;
++
++ QDir d( home );
++ d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
++ d.setNameFilter( ".DCOPserver*" );
++
++ const QFileInfoList *list = d.entryInfoList();
++ if( !list )
++ return result;
++
++ QFileInfoListIterator it( *list );
++ QFileInfo *fi;
++
++ while ( ( fi = it.current() ) != 0 )
++ {
++ if( fi->isReadable() )
++ result.append( fi->fileName() );
++ ++it;
++ }
++ return result;
++}
+
++/**
++ * Do the actual DCOP call
++ */
++void runDCOP( QCStringList args, UserList users, Session session,
++ const QString sessionName, bool readStdin )
++{
+ QCString app;
+ QCString objid;
+ QCString function;
+- char **args = 0;
+- if ((argc > 1) && (strncmp(argv[1], "DCOPRef(", 8)) == 0)
++ QCStringList params;
++ DCOPClient *client = 0L;
++ if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
+ {
+- char *delim = strchr(argv[1], ',');
+- if (!delim)
+- {
+- fprintf(stderr, "Error: '%s' is not a valid DCOP reference.\n", argv[1]);
+- return 1;
+- }
+- *delim = 0;
+- app = argv[1] + 8;
+- delim++;
+- delim[strlen(delim)-1] = 0;
+- objid = delim;
+- if (argc > 2)
+- function = argv[2];
+- if (argc > 3)
+- args = &argv[3];
+- argc++;
++ // WARNING: This part (until the closing '}') could very
++ // well be broken now. As I don't know how to trigger and test
++ // dcoprefs this code is *not* tested. It compiles and it looks
++ // ok to me, but that's all I can say - Martijn (2001/12/24)
++ int delimPos = args[ 0 ].findRev( ',' );
++ if( delimPos == -1 )
++ {
++ cerr << "Error: '" << args[ 0 ]
++ << "' is not a valid DCOP reference." << endl;
++ exit( -1 );
++ }
++ args[ 0 ][ delimPos ] = 0;
++ app = args[ 0 ].mid( 8 );
++ delimPos++;
++ args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
++ objid = args[ 0 ].mid( delimPos );
++ if( args.count() > 1 )
++ function = args[ 1 ];
++ if( args.count() > 2 )
++ {
++ params = args;
++ params.remove( params.begin() );
++ params.remove( params.begin() );
++ }
+ }
+ else
+ {
+- if (argc > 1)
+- app = argv[1];
+- if (argc > 2)
+- objid = argv[2];
+- if (argc > 3)
+- function = argv[3];
+- if (argc > 4)
+- args = &argv[4];
+- }
+-
+- switch ( argc ) {
+- case 0:
+- case 1:
+- queryApplications("");
+- break;
+- case 2:
+- if (endsWith(app, '*'))
+- queryApplications(app);
+- else
+- queryObjects( app, "" );
+- break;
+- case 3:
+- if (endsWith(objid, '*'))
+- queryObjects(app, objid);
+- else
+- queryFunctions( app, objid );
+- break;
+- case 4:
+- default:
+- callFunction( app, objid, function, argc - 4, args );
+- break;
++ if( !args.isEmpty() )
++ app = args[ 0 ];
++ if( args.count() > 1 )
++ objid = args[ 1 ];
++ if( args.count() > 2 )
++ function = args[ 2 ];
++ if( args.count() > 3)
++ {
++ params = args;
++ params.remove( params.begin() );
++ params.remove( params.begin() );
++ params.remove( params.begin() );
++ }
++ }
++
++ bool firstRun = true;
++ UserList::Iterator it;
++ QStringList sessions;
++ bool presetDCOPServer = false;
++// char *dcopStr = 0L;
++ QString dcopServer;
++
++ for( it = users.begin(); it != users.end() || firstRun; it++ )
++ {
++ firstRun = false;
++
++ //cout << "Iterating '" << it.key() << "'" << endl;
++
++ if( session == QuerySessions )
++ {
++ QStringList sessions = dcopSessionList( it.key(), it.data() );
++ if( sessions.isEmpty() )
++ {
++ cout << "No active sessions";
++ if( !( *it ).isEmpty() )
++ cout << " for user " << *it;
++ cout << endl;
++ }
++ else
++ {
++ cout << "Active sessions ";
++ if( !( *it ).isEmpty() )
++ cout << "for user " << *it << " ";
++ cout << ":" << endl;
++
++ QStringList::Iterator sIt;
++ for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
++ cout << " " << *sIt << endl;
++
++ cout << endl;
++ }
++ continue;
++ }
++
++ if( getenv( "DCOPSERVER" ) )
++ {
++ sessions.append( getenv( "DCOPSERVER" ) );
++ presetDCOPServer = true;
++ }
++
++ if( users.count() > 1 || ( users.count() == 1 &&
++ ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
++ {
++ sessions = dcopSessionList( it.key(), it.data() );
++ if( sessions.isEmpty() )
++ {
++ if( users.count() > 1 )
++ continue;
++ else
++ {
++ cerr << "ERROR: No active KDE sessions!" << endl
++ << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
++ << "before calling dcop." << endl;
++ exit( -1 );
++ }
++ }
++ else if( sessions.count() > 1 && session != AllSessions )
++ {
++ cerr << "ERROR: Multiple available KDE sessions!" << endl
++ << "Please specify the correct session to use with --session or use the" << endl
++ << "--all-sessions option to broadcast to all sessions." << endl;
++ exit( -1 );
++ }
++ }
+
++ if( users.count() > 1 || ( users.count() == 1 &&
++ ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
++ {
++ // Check for ICE authority file and if the file can be read by us
++ QString home = it.data();
++ QString iceFile = it.data() + "/.ICEauthority";
++ QFileInfo fi( iceFile );
++ if( iceFile.isEmpty() )
++ {
++ cerr << "WARNING: Cannot determine home directory for user "
++ << it.key() << "!" << endl
++ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
++ << "calling dcop." << endl;
++ }
++ else if( fi.exists() )
++ {
++ if( fi.isReadable() )
++ {
++ char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
++ putenv( envStr );
++ //cerr << "ice: " << envStr << endl;
++ }
++ else
++ {
++ cerr << "WARNING: ICE authority file " << iceFile
++ << "is not readable by you!" << endl
++ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
++ << "calling dcop." << endl;
++ }
++ }
++ else
++ {
++ if( users.count() > 1 )
++ continue;
++ else
++ {
++ cerr << "WARNING: Cannot find ICE authority file "
++ << iceFile << "!" << endl
++ << "Please check permissions or set the $ICEAUTHORITY"
++ << " variable manually before" << endl
++ << "calling dcop." << endl;
++ }
++ }
++ }
++
++ // Main loop
++ // If users is an empty list we're calling for the currently logged
++ // in user. In this case we don't have a session, but still want
++ // to iterate the loop once.
++ QStringList::Iterator sIt = sessions.begin();
++ for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
++ {
++ if( !presetDCOPServer && !users.isEmpty() )
++ {
++ QString dcopFile = it.data() + "/" + *sIt;
++ QFile f( dcopFile );
++ if( !f.open( IO_ReadOnly ) )
++ {
++ cerr << "Can't open " << dcopFile << " for reading!" << endl;
++ exit( -1 );
++ }
++
++ QStringList l( QStringList::split( '\n', f.readAll() ) );
++ dcopServer = l.first();
++
++ if( dcopServer.isEmpty() )
++ {
++ cerr << "WARNING: Unable to determine DCOP server for session "
++ << *sIt << "!" << endl
++ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
++ << "calling dcop." << endl;
++ exit( -1 );
++ }
++ }
++
++ delete client;
++ client = new DCOPClient;
++ if( !dcopServer.isEmpty() )
++ client->setServerAddress( dcopServer.ascii() );
++ bool success = client->attach();
++ if( !success )
++ {
++ cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
++ continue;
++ }
++ dcop = client;
++
++ switch ( args.count() )
++ {
++ case 0:
++ queryApplications("");
++ break;
++ case 1:
++ if (endsWith(app, '*'))
++ queryApplications(app);
++ else
++ queryObjects( app, "" );
++ break;
++ case 2:
++ if (endsWith(objid, '*'))
++ queryObjects(app, objid);
++ else
++ queryFunctions( app, objid );
++ break;
++ case 3:
++ default:
++ if( readStdin )
++ {
++ QCStringList::Iterator replaceArg = args.end();
++
++ QCStringList::Iterator it;
++ for( it = args.begin(); it != args.end(); it++ )
++ if( *it == "%1" )
++ replaceArg = it;
++
++ // Read from stdin until EOF and call function for each line read
++ char *buf = new char[ 1000 ];
++ while ( !feof( stdin ) )
++ {
++ fgets( buf, 1000, stdin );
++
++ if( replaceArg != args.end() )
++ *replaceArg = buf;
++
++ callFunction( app, objid, function, params );
++ }
++ }
++ else
++ {
++ // Just call function
++// cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
++ callFunction( app, objid, function, params );
++ }
++ break;
++ }
++ // Another sIt++ would make the loop infinite...
++ if( users.isEmpty() )
++ break;
++ }
++
++ // Another it++ would make the loop infinite...
++ if( it == users.end() )
++ break;
+ }
++}
++
+
++int main( int argc, char** argv )
++{
++ bool readStdin = false;
++ int numOptions = 0;
++ QString user;
++ Session session = DefaultSession;
++ QString sessionName;
++
++ // Scan for command-line options first
++ for( int pos = 1 ; pos <= argc - 1 ; pos++ )
++ {
++ if( strcmp( argv[ pos ], "--help" ) == 0 )
++ showHelp( 0 );
++ else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
++ {
++ readStdin = true;
++ numOptions++;
++ }
++ else if( strcmp( argv[ pos ], "--user" ) == 0 )
++ {
++ if( pos <= argc - 2 )
++ {
++ user = QString::fromLocal8Bit( argv[ pos + 1] );
++ numOptions +=2;
++ pos++;
++ }
++ else
++ {
++ cerr << "Missing username for '--user' option!" << endl << endl;
++ showHelp( -1 );
++ }
++ }
++ else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
++ {
++ user = "*";
++ numOptions ++;
++ }
++ else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
++ {
++ session = QuerySessions;
++ numOptions ++;
++ }
++ else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
++ {
++ session = AllSessions;
++ numOptions ++;
++ }
++ else if( argv[ pos ][ 0 ] == '-' )
++ {
++ cerr << "Unknown command-line option '" << argv[ pos ]
++ << "'." << endl << endl;
++ showHelp( -1 );
++ }
++ else
++ break; // End of options
++ }
++
++ argc -= numOptions;
++
++ QCStringList args;
++ for( int i = numOptions; i < argc + numOptions - 1; i++ )
++ args.append( argv[ i + 1 ] );
++
++ if( readStdin && args.count() < 3 )
++ {
++ cerr << "--pipe option only supported for function calls!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ if( user == "*" && args.count() < 3 && session != QuerySessions )
++ {
++ cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ if( session == QuerySessions && !args.isEmpty() )
++ {
++ cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ if( session == QuerySessions && user.isEmpty() )
++ {
++ cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
++ << "--all-users options!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ if( session != DefaultSession && session != QuerySessions &&
++ args.count() < 3 )
++ {
++ cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
++ << "calls!" << endl << endl;
++ showHelp( -1 );
++ }
++
++ UserList users;
++ if( user == "*" )
++ users = userList();
++ else if( !user.isEmpty() )
++ users[ user ] = userList()[ user ];
++
++ runDCOP( args, users, session, sessionName, readStdin );
++
+ return 0;
+ }
++
++// vim: set ts=8 sts=4 sw=4 noet:
++
+Index: client/dcopfind.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
+retrieving revision 1.2
+diff -u -r1.2 dcopfind.cpp
+--- client/dcopfind.cpp 2001/10/31 01:17:39 1.2
++++ client/dcopfind.cpp 2002/01/16 18:06:14
+@@ -36,7 +36,7 @@
+ static bool bAppIdOnly = 0;
+ static bool bLaunchApp = 0;
+
+-bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
++bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
+ {
+ QString f = func; // Qt is better with unicode strings, so use one.
+ int left = f.find( '(' );
+@@ -118,7 +118,7 @@
+ f = fc;
+ }
+
+- if ( (int) types.count() != argc ) {
++ if ( types.count() != args.count() ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+@@ -128,9 +128,9 @@
+
+ int i = 0;
+ for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
+- marshall(arg, argc, args, i, *it);
++ marshall(arg, args, i, *it);
+ }
+- if ( (int) i != argc ) {
++ if ( (uint) i != args.count() ) {
+ qWarning( "arguments do not match" );
+ exit(1);
+ }
+@@ -221,7 +221,11 @@
+ argc = 0;
+ }
+
+- findObject( app, objid, function, argc, args );
++ QCStringList params;
++ for( int i = 0; i < argc; i++ )
++ params.append( args[ i ] );
++
++ findObject( app, objid, function, params );
+
+ return 0;
+ }
+Index: client/marshall.cpp
+===================================================================
+RCS file: /home/kde/kdelibs/dcop/client/marshall.cpp,v
+retrieving revision 1.3
+diff -u -r1.3 marshall.cpp
+--- client/marshall.cpp 2001/10/31 01:17:39 1.3
++++ client/marshall.cpp 2002/01/16 18:06:14
+@@ -242,108 +242,110 @@
+
+ }
+
+-void marshall(QDataStream &arg, int argc, char **argv, int &i, QString type)
++void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
+ {
+- if (type == "QStringList")
+- type = "QValueList<QString>";
+- if (type == "QCStringList")
+- type = "QValueList<QCString>";
+- if (i >= argc)
+- {
+- qWarning("Not enough arguments.");
+- exit(1);
+- }
+- QString s = QString::fromLocal8Bit(argv[i]);
+-
+- if ( type == "int" )
+- arg << s.toInt();
+- else if ( type == "uint" )
+- arg << s.toUInt();
+- else if ( type == "unsigned" )
+- arg << s.toUInt();
+- else if ( type == "unsigned int" )
+- arg << s.toUInt();
+- else if ( type == "long" )
+- arg << s.toLong();
+- else if ( type == "long int" )
+- arg << s.toLong();
+- else if ( type == "unsigned long" )
+- arg << s.toULong();
+- else if ( type == "unsigned long int" )
+- arg << s.toULong();
+- else if ( type == "float" )
+- arg << s.toFloat();
+- else if ( type == "double" )
+- arg << s.toDouble();
+- else if ( type == "bool" )
+- arg << mkBool( s );
+- else if ( type == "QString" )
+- arg << s;
+- else if ( type == "QCString" )
+- arg << QCString( argv[i] );
+- else if ( type == "QColor" )
+- arg << mkColor( s );
+- else if ( type == "QPoint" )
+- arg << mkPoint( s );
+- else if ( type == "QSize" )
+- arg << mkSize( s );
+- else if ( type == "QRect" )
+- arg << mkRect( s );
+- else if ( type == "QVariant" ) {
+- if ( s == "true" || s == "false" )
+- arg << QVariant( mkBool( s ), 42 );
+- else if ( s.left( 4 ) == "int(" )
+- arg << QVariant( s.mid(4, s.length()-5).toInt() );
+- else if ( s.left( 7 ) == "QPoint(" )
+- arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
+- else if ( s.left( 6 ) == "QSize(" )
+- arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
+- else if ( s.left( 6 ) == "QRect(" )
+- arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
+- else if ( s.left( 7 ) == "QColor(" )
+- arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
+- else
+- arg << QVariant( s );
+- } else if ( type.startsWith("QValueList<")) {
+- type = type.mid(11, type.length() - 12);
+- QStringList list;
+- QString delim = s;
+- if (delim == "[")
+- delim = "]";
+- if (delim == "(")
+- delim = ")";
+- i++;
+- QByteArray dummy_data;
+- QDataStream dummy_arg(dummy_data, IO_WriteOnly);
++ if (type == "QStringList")
++ type = "QValueList<QString>";
++ if (type == "QCStringList")
++ type = "QValueList<QCString>";
++ if( i > args.count() )
++ {
++ qWarning("Not enough arguments.");
++ exit(1);
++ }
++ QString s = QString::fromLocal8Bit( args[ i ] );
+
+- int j = i;
+- int count = 0;
+- // Parse list to get the count
+- while (true) {
+- if (j >= argc)
+- {
+- qWarning("List end-delimiter '%s' not found.", delim.latin1());
+- exit(1);
+- }
+- if (argv[j] == delim) break;
+- marshall(dummy_arg, argc, argv, j, type);
+- count++;
+- }
+- arg << (Q_UINT32) count;
+- // Parse the list for real
+- while (true) {
+- if (i >= argc)
+- {
+- qWarning("List end-delimiter '%s' not found.", delim.latin1());
+- exit(1);
+- }
+- if (argv[i] == delim) break;
+- marshall(arg, argc, argv, i, type);
+- }
+- } else {
+- qWarning( "cannot handle datatype '%s'", type.latin1() );
+- exit(1);
+- }
++ if ( type == "int" )
++ arg << s.toInt();
++ else if ( type == "uint" )
++ arg << s.toUInt();
++ else if ( type == "unsigned" )
++ arg << s.toUInt();
++ else if ( type == "unsigned int" )
++ arg << s.toUInt();
++ else if ( type == "long" )
++ arg << s.toLong();
++ else if ( type == "long int" )
++ arg << s.toLong();
++ else if ( type == "unsigned long" )
++ arg << s.toULong();
++ else if ( type == "unsigned long int" )
++ arg << s.toULong();
++ else if ( type == "float" )
++ arg << s.toFloat();
++ else if ( type == "double" )
++ arg << s.toDouble();
++ else if ( type == "bool" )
++ arg << mkBool( s );
++ else if ( type == "QString" )
++ arg << s;
++ else if ( type == "QCString" )
++ arg << QCString( args[ i ] );
++ else if ( type == "QColor" )
++ arg << mkColor( s );
++ else if ( type == "QPoint" )
++ arg << mkPoint( s );
++ else if ( type == "QSize" )
++ arg << mkSize( s );
++ else if ( type == "QRect" )
++ arg << mkRect( s );
++ else if ( type == "QVariant" ) {
++ if ( s == "true" || s == "false" )
++ arg << QVariant( mkBool( s ), 42 );
++ else if ( s.left( 4 ) == "int(" )
++ arg << QVariant( s.mid(4, s.length()-5).toInt() );
++ else if ( s.left( 7 ) == "QPoint(" )
++ arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
++ else if ( s.left( 6 ) == "QSize(" )
++ arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
++ else if ( s.left( 6 ) == "QRect(" )
++ arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
++ else if ( s.left( 7 ) == "QColor(" )
++ arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
++ else
++ arg << QVariant( s );
++ } else if ( type.startsWith("QValueList<")) {
++ type = type.mid(11, type.length() - 12);
++ QStringList list;
++ QString delim = s;
++ if (delim == "[")
++ delim = "]";
++ if (delim == "(")
++ delim = ")";
+ i++;
++ QByteArray dummy_data;
++ QDataStream dummy_arg(dummy_data, IO_WriteOnly);
++
++ uint j = i;
++ uint count = 0;
++ // Parse list to get the count
++ while (true) {
++ if( j > args.count() )
++ {
++ qWarning("List end-delimiter '%s' not found.", delim.latin1());
++ exit(1);
++ }
++ if( QString::fromLocal8Bit( args[ j ] ) == delim )
++ break;
++ marshall( dummy_arg, args, j, type );
++ count++;
++ }
++ arg << (Q_UINT32) count;
++ // Parse the list for real
++ while (true) {
++ if( i > args.count() )
++ {
++ qWarning("List end-delimiter '%s' not found.", delim.latin1());
++ exit(1);
++ }
++ if( QString::fromLocal8Bit( args[ i ] ) == delim )
++ break;
++ marshall( arg, args, i, type );
++ }
++ } else {
++ qWarning( "cannot handle datatype '%s'", type.latin1() );
++ exit(1);
++ }
++ i++;
+ }
+