summaryrefslogtreecommitdiffstats
path: root/kompare/tests
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
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')
-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
-rw-r--r--kompare/tests/diff/context.diff27
-rw-r--r--kompare/tests/diff/contextm.diff1032
-rw-r--r--kompare/tests/diff/contextp.diff27
-rw-r--r--kompare/tests/diff/ed.diff10
-rw-r--r--kompare/tests/diff/edm.diff680
-rw-r--r--kompare/tests/diff/normal.diff12
-rw-r--r--kompare/tests/diff/normalm.diff849
-rw-r--r--kompare/tests/diff/rcs.diff9
-rw-r--r--kompare/tests/diff/rcsm.diff671
-rw-r--r--kompare/tests/diff/unified.diff19
-rw-r--r--kompare/tests/diff/unifiedm.diff911
-rw-r--r--kompare/tests/diff/unifiedp.diff19
-rw-r--r--kompare/tests/perforce/context.diff8
-rw-r--r--kompare/tests/perforce/contextm.diff23
-rw-r--r--kompare/tests/perforce/rcs.diff3
-rw-r--r--kompare/tests/perforce/rcsm.diff12
-rw-r--r--kompare/tests/perforce/unified.diff6
-rw-r--r--kompare/tests/perforce/unifiedm.diff19
-rw-r--r--kompare/tests/subversion/context.diff9
-rw-r--r--kompare/tests/subversion/contextm.diff180
-rw-r--r--kompare/tests/subversion/ed.diff5
-rw-r--r--kompare/tests/subversion/edm.diff57
-rw-r--r--kompare/tests/subversion/normal.diff6
-rw-r--r--kompare/tests/subversion/normalm.diff170
-rw-r--r--kompare/tests/subversion/rcs.diff5
-rw-r--r--kompare/tests/subversion/rcsm.diff55
-rw-r--r--kompare/tests/subversion/unified.diff7
-rw-r--r--kompare/tests/subversion/unifiedm.diff173
38 files changed, 9420 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++;
+ }
+
diff --git a/kompare/tests/diff/context.diff b/kompare/tests/diff/context.diff
new file mode 100644
index 00000000..e17df000
--- /dev/null
+++ b/kompare/tests/diff/context.diff
@@ -0,0 +1,27 @@
+*** /home/John/lao Thu Apr 12 11:09:30 2001
+--- /home/John/tzu Sat Jul 28 13:23:25 2001
+***************
+*** 1,7 ****
+- The Way that can be told of is not the eternal Way;
+- The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+! The Named is the mother of all things.
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+--- 1,6 ----
+ The Nameless is the origin of Heaven and Earth;
+! The named is the mother of all things.
+!
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+***************
+*** 9,11 ****
+--- 8,13 ----
+ The two are the same,
+ But after they are produced,
+ they have different names.
++ They both may be called deep and profound.
++ Deeper and more profound,
++ The door of all subtleties!
diff --git a/kompare/tests/diff/contextm.diff b/kompare/tests/diff/contextm.diff
new file mode 100644
index 00000000..0b1bba5a
--- /dev/null
+++ b/kompare/tests/diff/contextm.diff
@@ -0,0 +1,1032 @@
+diff -cr dcop/client/dcop.cpp dcop2/client/dcop.cpp
+*** dcop/client/dcop.cpp Wed Jan 30 22:38:07 2002
+--- dcop2/client/dcop.cpp Wed Jan 30 22:37:04 2002
+***************
+*** 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);
+ }
+***************
+*** 266,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;
+ }
+--- 295,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:
++
+diff -cr dcop/client/dcopfind.cpp dcop2/client/dcopfind.cpp
+*** dcop/client/dcopfind.cpp Wed Jan 30 22:38:07 2002
+--- dcop2/client/dcopfind.cpp Wed Jan 30 22:37:04 2002
+***************
+*** 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 -cr dcop/client/marshall.cpp dcop2/client/marshall.cpp
+*** dcop/client/marshall.cpp Wed Jan 30 22:38:07 2002
+--- dcop2/client/marshall.cpp Wed Jan 30 22:37:04 2002
+***************
+*** 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/diff/contextp.diff b/kompare/tests/diff/contextp.diff
new file mode 100644
index 00000000..ed9319bc
--- /dev/null
+++ b/kompare/tests/diff/contextp.diff
@@ -0,0 +1,27 @@
+*** /home/John/lao Thu Apr 12 11:09:30 2001
+--- /home/John/tzu Sat Jul 28 13:23:25 2001
+***************
+*** 1,7 ****
+- The Way that can be told of is not the eternal Way;
+- The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+! The Named is the mother of all things.
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+--- 1,6 ----
+ The Nameless is the origin of Heaven and Earth;
+! The named is the mother of all things.
+!
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+*************** And let there always be being,
+*** 9,11 ****
+--- 8,13 ----
+ The two are the same,
+ But after they are produced,
+ they have different names.
++ They both may be called deep and profound.
++ Deeper and more profound,
++ The door of all subtleties!
diff --git a/kompare/tests/diff/ed.diff b/kompare/tests/diff/ed.diff
new file mode 100644
index 00000000..43c2b2f1
--- /dev/null
+++ b/kompare/tests/diff/ed.diff
@@ -0,0 +1,10 @@
+11a
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!
+.
+4c
+The named is the mother of all things.
+
+.
+1,2d
diff --git a/kompare/tests/diff/edm.diff b/kompare/tests/diff/edm.diff
new file mode 100644
index 00000000..0df2abc1
--- /dev/null
+++ b/kompare/tests/diff/edm.diff
@@ -0,0 +1,680 @@
+diff -er dcop/client/dcop.cpp dcop2/client/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>
+
+.
+diff -er dcop/client/dcopfind.cpp dcop2/client/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 -er dcop/client/marshall.cpp dcop2/client/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/diff/normal.diff b/kompare/tests/diff/normal.diff
new file mode 100644
index 00000000..6f82a1c4
--- /dev/null
+++ b/kompare/tests/diff/normal.diff
@@ -0,0 +1,12 @@
+1,2d0
+< The Way that can be told of is not the eternal Way;
+< The name that can be named is not the eternal name.
+4c2,3
+< The Named is the mother of all things.
+---
+> The named is the mother of all things.
+>
+11a11,13
+> They both may be called deep and profound.
+> Deeper and more profound,
+> The door of all subtleties!
diff --git a/kompare/tests/diff/normalm.diff b/kompare/tests/diff/normalm.diff
new file mode 100644
index 00000000..3db667ba
--- /dev/null
+++ b/kompare/tests/diff/normalm.diff
@@ -0,0 +1,849 @@
+diff -r dcop/client/dcop.cpp dcop2/client/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:
+>
+diff -r dcop/client/dcopfind.cpp dcop2/client/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 -r dcop/client/marshall.cpp dcop2/client/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/diff/rcs.diff b/kompare/tests/diff/rcs.diff
new file mode 100644
index 00000000..08069790
--- /dev/null
+++ b/kompare/tests/diff/rcs.diff
@@ -0,0 +1,9 @@
+d1 2
+d4 1
+a4 2
+The named is the mother of all things.
+
+a11 3
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!
diff --git a/kompare/tests/diff/rcsm.diff b/kompare/tests/diff/rcsm.diff
new file mode 100644
index 00000000..0c4222f9
--- /dev/null
+++ b/kompare/tests/diff/rcsm.diff
@@ -0,0 +1,671 @@
+diff -nr dcop/client/dcop.cpp dcop2/client/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:
+
+diff -nr dcop/client/dcopfind.cpp dcop2/client/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 -nr dcop/client/marshall.cpp dcop2/client/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/diff/unified.diff b/kompare/tests/diff/unified.diff
new file mode 100644
index 00000000..952e648c
--- /dev/null
+++ b/kompare/tests/diff/unified.diff
@@ -0,0 +1,19 @@
+--- /home/John/lao Thu Apr 12 11:09:30 2001
++++ /home/John/tzu Sat Jul 28 13:23:25 2001
+@@ -1,7 +1,6 @@
+-The Way that can be told of is not the eternal Way;
+-The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+-The Named is the mother of all things.
++The named is the mother of all things.
++
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+@@ -9,3 +8,6 @@
+ The two are the same,
+ But after they are produced,
+ they have different names.
++They both may be called deep and profound.
++Deeper and more profound,
++The door of all subtleties!
diff --git a/kompare/tests/diff/unifiedm.diff b/kompare/tests/diff/unifiedm.diff
new file mode 100644
index 00000000..4a30c6b4
--- /dev/null
+++ b/kompare/tests/diff/unifiedm.diff
@@ -0,0 +1,911 @@
+diff -aur dcop/client/dcop.cpp dcop2/client/dcop.cpp
+--- dcop/client/dcop.cpp Wed Jan 30 22:38:07 2002
++++ dcop2/client/dcop.cpp Wed Jan 30 22:37:04 2002
+@@ -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);
+ }
+@@ -266,78 +295,479 @@
+ }
+ }
+
++/**
++ * 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:
++
+diff -aur dcop/client/dcopfind.cpp dcop2/client/dcopfind.cpp
+--- dcop/client/dcopfind.cpp Wed Jan 30 22:38:07 2002
++++ dcop2/client/dcopfind.cpp Wed Jan 30 22:37:04 2002
+@@ -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 -aur dcop/client/marshall.cpp dcop2/client/marshall.cpp
+--- dcop/client/marshall.cpp Wed Jan 30 22:38:07 2002
++++ dcop2/client/marshall.cpp Wed Jan 30 22:37:04 2002
+@@ -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++;
+ }
+
diff --git a/kompare/tests/diff/unifiedp.diff b/kompare/tests/diff/unifiedp.diff
new file mode 100644
index 00000000..891b8b8d
--- /dev/null
+++ b/kompare/tests/diff/unifiedp.diff
@@ -0,0 +1,19 @@
+--- /home/John/lao Thu Apr 12 11:09:30 2001
++++ /home/John/tzu Sat Jul 28 13:23:25 2001
+@@ -1,7 +1,6 @@
+-The Way that can be told of is not the eternal Way;
+-The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+-The Named is the mother of all things.
++The named is the mother of all things.
++
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+@@ -9,3 +8,6 @@ And let there always be being,
+ The two are the same,
+ But after they are produced,
+ they have different names.
++They both may be called deep and profound.
++Deeper and more profound,
++The door of all subtleties!
diff --git a/kompare/tests/perforce/context.diff b/kompare/tests/perforce/context.diff
new file mode 100644
index 00000000..a25c2461
--- /dev/null
+++ b/kompare/tests/perforce/context.diff
@@ -0,0 +1,8 @@
+==== //depot/testje#2 - /home/bruggie/perforce-repo/testje ====
+***************
+*** 3,5 ****
+--- 3,6 ----
+
+ but i
+ 'll see what this is all about later on
++ More lines for #3 to see what happens in a multifile diff
diff --git a/kompare/tests/perforce/contextm.diff b/kompare/tests/perforce/contextm.diff
new file mode 100644
index 00000000..07380b31
--- /dev/null
+++ b/kompare/tests/perforce/contextm.diff
@@ -0,0 +1,23 @@
+==== //depot/craphola#1 - /home/bruggie/perforce-repo/craphola ====
+***************
+*** 2,4 ****
+--- 2,11 ----
+ I'm just adding this file to see what it does with multiple file that have differences
+
+ Now i'll add some text more later in the #2 revision but that has to wait a bit
++
++ This will be a copy and paste of the previous lines just to have some changes for revision 2 of this file
++
++ This is another t4extfile used to test the perforce diff stuff
++ I'm just adding this file to see what it does with multiple file that have differences
++
++ Now i'll add some text more later in the #2 revision but that has to wait a bit
+==== //depot/testje#2 - /home/bruggie/perforce-repo/testje ====
+***************
+*** 3,5 ****
+--- 3,7 ----
+
+ but i
+ 'll see what this is all about later on
++
++ More lines for #3 to see what happens in a multifile diff
diff --git a/kompare/tests/perforce/rcs.diff b/kompare/tests/perforce/rcs.diff
new file mode 100644
index 00000000..ce99087d
--- /dev/null
+++ b/kompare/tests/perforce/rcs.diff
@@ -0,0 +1,3 @@
+==== //depot/testje#2 - /home/bruggie/perforce-repo/testje ====
+a5 1
+More lines for #3 to see what happens in a multifile diff
diff --git a/kompare/tests/perforce/rcsm.diff b/kompare/tests/perforce/rcsm.diff
new file mode 100644
index 00000000..bee028a0
--- /dev/null
+++ b/kompare/tests/perforce/rcsm.diff
@@ -0,0 +1,12 @@
+==== //depot/craphola#1 - /home/bruggie/perforce-repo/craphola ====
+a4 7
+
+This will be a copy and paste of the previous lines just to have some changes for revision 2 of this file
+
+This is another t4extfile used to test the perforce diff stuff
+I'm just adding this file to see what it does with multiple file that have differences
+
+Now i'll add some text more later in the #2 revision but that has to wait a bit
+==== //depot/testje#2 - /home/bruggie/perforce-repo/testje ====
+a5 2
+More lines for #3 to see what happens in a multifile diff
diff --git a/kompare/tests/perforce/unified.diff b/kompare/tests/perforce/unified.diff
new file mode 100644
index 00000000..f9235ba9
--- /dev/null
+++ b/kompare/tests/perforce/unified.diff
@@ -0,0 +1,6 @@
+==== //depot/testje#2 - /home/bruggie/perforce-repo/testje ====
+@@ -3,3 +3,4 @@
+
+ but i
+ 'll see what this is all about later on
++More lines for #3 to see what happens in a multifile diff
diff --git a/kompare/tests/perforce/unifiedm.diff b/kompare/tests/perforce/unifiedm.diff
new file mode 100644
index 00000000..6aa832e7
--- /dev/null
+++ b/kompare/tests/perforce/unifiedm.diff
@@ -0,0 +1,19 @@
+==== //depot/craphola#1 - /home/bruggie/perforce-repo/craphola ====
+@@ -2,3 +2,10 @@
+ I'm just adding this file to see what it does with multiple file that have differences
+
+ Now i'll add some text more later in the #2 revision but that has to wait a bit
++
++This will be a copy and paste of the previous lines just to have some changes for revision 2 of this file
++
++This is another t4extfile used to test the perforce diff stuff
++I'm just adding this file to see what it does with multiple file that have differences
++
++Now i'll add some text more later in the #2 revision but that has to wait a bit
+==== //depot/testje#2 - /home/bruggie/perforce-repo/testje ====
+@@ -3,3 +3,5 @@
+
+ but i
+ 'll see what this is all about later on
++
++More lines for #3 to see what happens in a multifile diff
diff --git a/kompare/tests/subversion/context.diff b/kompare/tests/subversion/context.diff
new file mode 100644
index 00000000..b8380037
--- /dev/null
+++ b/kompare/tests/subversion/context.diff
@@ -0,0 +1,9 @@
+Index: NEWS
+===================================================================
+*** NEWS
+--- NEWS Sun Sep 22 14:34:37 2002
+***************
+*** 1 ****
+!
+--- 1 ----
+! just a fake modif for kompare tests
diff --git a/kompare/tests/subversion/contextm.diff b/kompare/tests/subversion/contextm.diff
new file mode 100644
index 00000000..fbb61263
--- /dev/null
+++ b/kompare/tests/subversion/contextm.diff
@@ -0,0 +1,180 @@
+Index: NEWS
+===================================================================
+*** NEWS
+--- NEWS Sun Sep 22 14:34:37 2002
+***************
+*** 1 ****
+!
+--- 1 ----
+! just a fake modif for kompare tests
+Index: README
+===================================================================
+*** README
+--- README Fri Sep 13 23:05:48 2002
+***************
+*** 1,117 ****
+! Vim KPart
+!
+!
+! by Philippe Fremy <pfremy@kde.com>
+!
+!
+! Okay, I made it : a Vim KPart!
+!
+! This means that you can have Vim embedded inside Konqueror, and everywhere a
+! text ReadWrite or ReadOnly KPart is requested. Actually, there is almost no
+! place right now where this is the case in KDE. KMail uses its own editor,
+! KDEvelop uses its own editor, Kate uses some more powerful Kate component.
+!
+! But this only the beginning. Enabling a part in those programs shouldn't be
+! much hassle and you can probably help me do it. My hope is really to get
+! KDevelop use Vim.
+!
+!
+! ======= OBSOLETE ===========
+! Requirements:
+! -------------
+! To make this KPart work, you need a graphicial Vim version 6 with the client-server stuff feature activated and with the vim60-vimpart-patch.diff applied. The patch is in this dir. I hope to get it into the main Vim tree. KVim has already the patch but is slightly less stable that the original GVim. A big advantage of KVim is that you get the native KDE dialogs when vim asks a question.
+!
+!
+! ======= OBSOLETE ===========
+! Installation:
+! -------------
+! To make your vimpart work, you'll have to go into the vimpart directory and run "testVim your_patched_vim". If the test does work, a file goodVim will be created. You will be able to install and use the component. Else, the test will report why it fails (features missing in vim).
+!
+!
+!
+! ======= OBSOLETE ===========
+! Testing:
+! --------
+! If you want to see your component without installing it, you can do the
+! following:
+!
+! 1. configure, build. Then go into the Vimpart subdirectory.
+!
+! 2. Include the current Vimpart directory in your KDEDIRS:
+! export KDEDIRS=`pwd`:$KDEDIR
+!
+! 3. Symlink .libs to lib
+! ln -s .libs lib
+!
+! 4. Create pseudo share/services dir:
+! mkdir share; mkdir share/services;
+!
+! 5. Symlink to Vimpart.desktop:
+! ln -s Vimpart.desktop share/services/Vimpart.desktop
+!
+! 6. Create a pseudo share/config dir
+! mkdir share/config;
+!
+! 7. Symlink to vimwidgetrc
+! ln -s vimwidgetrc share/config/vimwidgetrc
+!
+! 8. Update the desktop mimetype database:
+! kbuildsycoca
+!
+! To test it, run VimPartShell. Or run konqueror from this dir and click on a
+! text file.
+!
+!
+! ======= OBSOLETE ===========
+! Remarks:
+! --------
+! The initial preference of the Vim KPart is 10. Kate uses 8, so if you install the part, it will override Kate for all the mimetypes. You can always change that by manually editing the initial preference in the desktop file or by simply selecting which editor you prefer for which mimetype in the control center.
+!
+! If you find some mimetype not handled by the Vim KPart although they should be, send me a patch!
+!
+!
+!
+! How it works:
+! -------------
+! At the beginning, we started to write KVim, a port of GVim to KDE to make
+! it possible to embed Vim inside KDE. But with the latest version of Vim, it
+! turns out that it is not necessary to have a native Vim.
+!
+!
+! I use QXembed, a widget which can embed any X application if it knows its X Window Id, using some X feature. The patch I provide will make vim displays its window id on stdout when the window is mapped. GVim 6.0 then provides a way to send commands to a Vim window from another process. If you look at the VimWidget source, you will see that 70% of the code is there to handle the communication process. The rest uses the communication channel to send the vim commands needed by kpart and ktexteditor.
+!
+! As far as I can tell, the part is race-condition free. If you issue many sendNormalCmd and many evalExpr, they are guaranted to be executed sequentially. This has caused me enough problems when it wasn't the case!
+!
+!
+! Qt, KDE2 and KDE3:
+! ------------------
+! The VimWidget itself depends very litle on KDE. It is quite easy to port remove the KDE specific stuff, to use it in a Qt only program. In fact, at the beginning, it was only Qt-based.
+!
+!
+!
+! ======= OBSOLETE ===========
+! Features & TODO:
+! ----------------
+! I think most basic features required by an editor widget or part are supported. There are some possible improvement but I would like more feedback to know what really needs to be done. So don't hesitate to write me about your feelings using this.
+!
+! My TODO list is:
+! - restore the editing mode after sendCmd
+! - implement KTextEditor interface
+! - add some useful actions to the part (like search, ...)
+!
+!
+!
+! Feedback:
+! ---------
+! For the Vim KPart : pfremy@kde.com
+! For KVim: pfremy@kde.org, mikmak@freenux.org, orzel@kde.org
+!
+!
+!
+!
+!
+!
+!
+
+
+
+--- 1,47 ----
+! Yes, that's really a Vim Komponent :)
+! Yes, you can have Vim inside KDE apps, you guessed it :)
+
++ So, it's designed for KDE 3.x (if someone wants to port it to KDE 2 that
++ should be easy), it uses GVim or KVim (even Motif Vim works) 6.x.
++ It can be used in different apps :
++ - KDevelop (version 3)
++ - Konqueror (as a file viewer)
++ - KWrite
++ - KMail (coming in KDE 3.2)
++ - Kompare, KBabel ........ ;)
++
++ CONFIGURATION
++ =============
++ once you compiled and installed it as any other app,
++ start your KDE Control Center, go to the file manager section
++ and open the Vim Component configuration module.
++ Here, you have to select a Vim executable which may be found on
++ your computer (generally /usr/bin/vim) will do it fine for most
++ linux distributions. All you need is that it's a GUI-enabled Vim 6.0 or
++ better.
++ Push the test button, if that's okay then that's should be enough to start
++ using it :)
++
++ FUNCTIONMENT
++ ============
++ Philippe Fremy (pfremy@kde.com) wrote the initial version of this kpart.
++ The concept is to start a normal GUI Vim (like gvim), then "embeds" the Vim
++ window into a KDE Widget.
++ It used to be based on the ClientServer feature of Vim (type :help
++ clientserver in Vim for more info) using external processus to control the
++ embedded Vim. That was running quite fine, but was slow :/
++ We changed that :)
++ Now we communicate directly from the kpart to the embedded Vim thanks to X11
++ without using externals processus. That's much faster and reliable ;)
++ KVim has also another remote control system using KDE's DCOP communication
++ backend.
++ Currently I would advice people to use DCOP when running KVim and using X11
++ communication with GVim (DCOP won't work with GVim anyway).
++ There may be some differences in speed, though I have not noticed it here.
++ The most important difference is that DCOP provides a signal system and that can
++ make a difference to improve the interaction between KVim and the hosting
++ application (KDevelop for example). But it's not yet used.
+
++ Hope you'll enjoy Vim inside KDE :)
++ Mickael "Mikmak" Marchand (marchand@kde.org)
+
diff --git a/kompare/tests/subversion/ed.diff b/kompare/tests/subversion/ed.diff
new file mode 100644
index 00000000..512b3880
--- /dev/null
+++ b/kompare/tests/subversion/ed.diff
@@ -0,0 +1,5 @@
+Index: NEWS
+===================================================================
+1c
+just a fake modif for kompare tests
+.
diff --git a/kompare/tests/subversion/edm.diff b/kompare/tests/subversion/edm.diff
new file mode 100644
index 00000000..dc51b21f
--- /dev/null
+++ b/kompare/tests/subversion/edm.diff
@@ -0,0 +1,57 @@
+Index: NEWS
+===================================================================
+1c
+just a fake modif for kompare tests
+.
+Index: README
+===================================================================
+116a
+Hope you'll enjoy Vim inside KDE :)
+Mickael "Mikmak" Marchand (marchand@kde.org)
+.
+115a
+So, it's designed for KDE 3.x (if someone wants to port it to KDE 2 that
+should be easy), it uses GVim or KVim (even Motif Vim works) 6.x.
+It can be used in different apps :
+ - KDevelop (version 3)
+ - Konqueror (as a file viewer)
+ - KWrite
+ - KMail (coming in KDE 3.2)
+ - Kompare, KBabel ........ ;)
+
+CONFIGURATION
+=============
+once you compiled and installed it as any other app,
+start your KDE Control Center, go to the file manager section
+and open the Vim Component configuration module.
+Here, you have to select a Vim executable which may be found on
+your computer (generally /usr/bin/vim) will do it fine for most
+linux distributions. All you need is that it's a GUI-enabled Vim 6.0 or
+better.
+Push the test button, if that's okay then that's should be enough to start
+using it :)
+
+FUNCTIONMENT
+============
+Philippe Fremy (pfremy@kde.com) wrote the initial version of this kpart.
+The concept is to start a normal GUI Vim (like gvim), then "embeds" the Vim
+window into a KDE Widget.
+It used to be based on the ClientServer feature of Vim (type :help
+clientserver in Vim for more info) using external processus to control the
+embedded Vim. That was running quite fine, but was slow :/
+We changed that :)
+Now we communicate directly from the kpart to the embedded Vim thanks to X11
+without using externals processus. That's much faster and reliable ;)
+KVim has also another remote control system using KDE's DCOP communication
+backend.
+Currently I would advice people to use DCOP when running KVim and using X11
+communication with GVim (DCOP won't work with GVim anyway).
+There may be some differences in speed, though I have not noticed it here.
+The most important difference is that DCOP provides a signal system and that can
+make a difference to improve the interaction between KVim and the hosting
+application (KDevelop for example). But it's not yet used.
+.
+1,114c
+Yes, that's really a Vim Komponent :)
+Yes, you can have Vim inside KDE apps, you guessed it :)
+.
diff --git a/kompare/tests/subversion/normal.diff b/kompare/tests/subversion/normal.diff
new file mode 100644
index 00000000..853cc219
--- /dev/null
+++ b/kompare/tests/subversion/normal.diff
@@ -0,0 +1,6 @@
+Index: NEWS
+===================================================================
+1c1
+<
+---
+> just a fake modif for kompare tests
diff --git a/kompare/tests/subversion/normalm.diff b/kompare/tests/subversion/normalm.diff
new file mode 100644
index 00000000..f526a3b0
--- /dev/null
+++ b/kompare/tests/subversion/normalm.diff
@@ -0,0 +1,170 @@
+Index: NEWS
+===================================================================
+1c1
+<
+---
+> just a fake modif for kompare tests
+Index: README
+===================================================================
+1,114c1,2
+< Vim KPart
+<
+<
+< by Philippe Fremy <pfremy@kde.com>
+<
+<
+< Okay, I made it : a Vim KPart!
+<
+< This means that you can have Vim embedded inside Konqueror, and everywhere a
+< text ReadWrite or ReadOnly KPart is requested. Actually, there is almost no
+< place right now where this is the case in KDE. KMail uses its own editor,
+< KDEvelop uses its own editor, Kate uses some more powerful Kate component.
+<
+< But this only the beginning. Enabling a part in those programs shouldn't be
+< much hassle and you can probably help me do it. My hope is really to get
+< KDevelop use Vim.
+<
+<
+< ======= OBSOLETE ===========
+< Requirements:
+< -------------
+< To make this KPart work, you need a graphicial Vim version 6 with the client-server stuff feature activated and with the vim60-vimpart-patch.diff applied. The patch is in this dir. I hope to get it into the main Vim tree. KVim has already the patch but is slightly less stable that the original GVim. A big advantage of KVim is that you get the native KDE dialogs when vim asks a question.
+<
+<
+< ======= OBSOLETE ===========
+< Installation:
+< -------------
+< To make your vimpart work, you'll have to go into the vimpart directory and run "testVim your_patched_vim". If the test does work, a file goodVim will be created. You will be able to install and use the component. Else, the test will report why it fails (features missing in vim).
+<
+<
+<
+< ======= OBSOLETE ===========
+< Testing:
+< --------
+< If you want to see your component without installing it, you can do the
+< following:
+<
+< 1. configure, build. Then go into the Vimpart subdirectory.
+<
+< 2. Include the current Vimpart directory in your KDEDIRS:
+< export KDEDIRS=`pwd`:$KDEDIR
+<
+< 3. Symlink .libs to lib
+< ln -s .libs lib
+<
+< 4. Create pseudo share/services dir:
+< mkdir share; mkdir share/services;
+<
+< 5. Symlink to Vimpart.desktop:
+< ln -s Vimpart.desktop share/services/Vimpart.desktop
+<
+< 6. Create a pseudo share/config dir
+< mkdir share/config;
+<
+< 7. Symlink to vimwidgetrc
+< ln -s vimwidgetrc share/config/vimwidgetrc
+<
+< 8. Update the desktop mimetype database:
+< kbuildsycoca
+<
+< To test it, run VimPartShell. Or run konqueror from this dir and click on a
+< text file.
+<
+<
+< ======= OBSOLETE ===========
+< Remarks:
+< --------
+< The initial preference of the Vim KPart is 10. Kate uses 8, so if you install the part, it will override Kate for all the mimetypes. You can always change that by manually editing the initial preference in the desktop file or by simply selecting which editor you prefer for which mimetype in the control center.
+<
+< If you find some mimetype not handled by the Vim KPart although they should be, send me a patch!
+<
+<
+<
+< How it works:
+< -------------
+< At the beginning, we started to write KVim, a port of GVim to KDE to make
+< it possible to embed Vim inside KDE. But with the latest version of Vim, it
+< turns out that it is not necessary to have a native Vim.
+<
+<
+< I use QXembed, a widget which can embed any X application if it knows its X Window Id, using some X feature. The patch I provide will make vim displays its window id on stdout when the window is mapped. GVim 6.0 then provides a way to send commands to a Vim window from another process. If you look at the VimWidget source, you will see that 70% of the code is there to handle the communication process. The rest uses the communication channel to send the vim commands needed by kpart and ktexteditor.
+<
+< As far as I can tell, the part is race-condition free. If you issue many sendNormalCmd and many evalExpr, they are guaranted to be executed sequentially. This has caused me enough problems when it wasn't the case!
+<
+<
+< Qt, KDE2 and KDE3:
+< ------------------
+< The VimWidget itself depends very litle on KDE. It is quite easy to port remove the KDE specific stuff, to use it in a Qt only program. In fact, at the beginning, it was only Qt-based.
+<
+<
+<
+< ======= OBSOLETE ===========
+< Features & TODO:
+< ----------------
+< I think most basic features required by an editor widget or part are supported. There are some possible improvement but I would like more feedback to know what really needs to be done. So don't hesitate to write me about your feelings using this.
+<
+< My TODO list is:
+< - restore the editing mode after sendCmd
+< - implement KTextEditor interface
+< - add some useful actions to the part (like search, ...)
+<
+<
+<
+< Feedback:
+< ---------
+< For the Vim KPart : pfremy@kde.com
+< For KVim: pfremy@kde.org, mikmak@freenux.org, orzel@kde.org
+<
+<
+<
+<
+<
+<
+<
+---
+> Yes, that's really a Vim Komponent :)
+> Yes, you can have Vim inside KDE apps, you guessed it :)
+115a4,43
+> So, it's designed for KDE 3.x (if someone wants to port it to KDE 2 that
+> should be easy), it uses GVim or KVim (even Motif Vim works) 6.x.
+> It can be used in different apps :
+> - KDevelop (version 3)
+> - Konqueror (as a file viewer)
+> - KWrite
+> - KMail (coming in KDE 3.2)
+> - Kompare, KBabel ........ ;)
+>
+> CONFIGURATION
+> =============
+> once you compiled and installed it as any other app,
+> start your KDE Control Center, go to the file manager section
+> and open the Vim Component configuration module.
+> Here, you have to select a Vim executable which may be found on
+> your computer (generally /usr/bin/vim) will do it fine for most
+> linux distributions. All you need is that it's a GUI-enabled Vim 6.0 or
+> better.
+> Push the test button, if that's okay then that's should be enough to start
+> using it :)
+>
+> FUNCTIONMENT
+> ============
+> Philippe Fremy (pfremy@kde.com) wrote the initial version of this kpart.
+> The concept is to start a normal GUI Vim (like gvim), then "embeds" the Vim
+> window into a KDE Widget.
+> It used to be based on the ClientServer feature of Vim (type :help
+> clientserver in Vim for more info) using external processus to control the
+> embedded Vim. That was running quite fine, but was slow :/
+> We changed that :)
+> Now we communicate directly from the kpart to the embedded Vim thanks to X11
+> without using externals processus. That's much faster and reliable ;)
+> KVim has also another remote control system using KDE's DCOP communication
+> backend.
+> Currently I would advice people to use DCOP when running KVim and using X11
+> communication with GVim (DCOP won't work with GVim anyway).
+> There may be some differences in speed, though I have not noticed it here.
+> The most important difference is that DCOP provides a signal system and that can
+> make a difference to improve the interaction between KVim and the hosting
+> application (KDevelop for example). But it's not yet used.
+116a45,46
+> Hope you'll enjoy Vim inside KDE :)
+> Mickael "Mikmak" Marchand (marchand@kde.org)
diff --git a/kompare/tests/subversion/rcs.diff b/kompare/tests/subversion/rcs.diff
new file mode 100644
index 00000000..1633c3a3
--- /dev/null
+++ b/kompare/tests/subversion/rcs.diff
@@ -0,0 +1,5 @@
+Index: NEWS
+===================================================================
+d1 1
+a1 1
+just a fake modif for kompare tests
diff --git a/kompare/tests/subversion/rcsm.diff b/kompare/tests/subversion/rcsm.diff
new file mode 100644
index 00000000..a409cd54
--- /dev/null
+++ b/kompare/tests/subversion/rcsm.diff
@@ -0,0 +1,55 @@
+Index: NEWS
+===================================================================
+d1 1
+a1 1
+just a fake modif for kompare tests
+Index: README
+===================================================================
+d1 114
+a114 2
+Yes, that's really a Vim Komponent :)
+Yes, you can have Vim inside KDE apps, you guessed it :)
+a115 40
+So, it's designed for KDE 3.x (if someone wants to port it to KDE 2 that
+should be easy), it uses GVim or KVim (even Motif Vim works) 6.x.
+It can be used in different apps :
+ - KDevelop (version 3)
+ - Konqueror (as a file viewer)
+ - KWrite
+ - KMail (coming in KDE 3.2)
+ - Kompare, KBabel ........ ;)
+
+CONFIGURATION
+=============
+once you compiled and installed it as any other app,
+start your KDE Control Center, go to the file manager section
+and open the Vim Component configuration module.
+Here, you have to select a Vim executable which may be found on
+your computer (generally /usr/bin/vim) will do it fine for most
+linux distributions. All you need is that it's a GUI-enabled Vim 6.0 or
+better.
+Push the test button, if that's okay then that's should be enough to start
+using it :)
+
+FUNCTIONMENT
+============
+Philippe Fremy (pfremy@kde.com) wrote the initial version of this kpart.
+The concept is to start a normal GUI Vim (like gvim), then "embeds" the Vim
+window into a KDE Widget.
+It used to be based on the ClientServer feature of Vim (type :help
+clientserver in Vim for more info) using external processus to control the
+embedded Vim. That was running quite fine, but was slow :/
+We changed that :)
+Now we communicate directly from the kpart to the embedded Vim thanks to X11
+without using externals processus. That's much faster and reliable ;)
+KVim has also another remote control system using KDE's DCOP communication
+backend.
+Currently I would advice people to use DCOP when running KVim and using X11
+communication with GVim (DCOP won't work with GVim anyway).
+There may be some differences in speed, though I have not noticed it here.
+The most important difference is that DCOP provides a signal system and that can
+make a difference to improve the interaction between KVim and the hosting
+application (KDevelop for example). But it's not yet used.
+a116 2
+Hope you'll enjoy Vim inside KDE :)
+Mickael "Mikmak" Marchand (marchand@kde.org)
diff --git a/kompare/tests/subversion/unified.diff b/kompare/tests/subversion/unified.diff
new file mode 100644
index 00000000..fca49ace
--- /dev/null
+++ b/kompare/tests/subversion/unified.diff
@@ -0,0 +1,7 @@
+Index: NEWS
+===================================================================
+--- NEWS
++++ NEWS 2002-09-22 14:34:37.000000000 +0200
+@@ -1 +1 @@
+-
++just a fake modif for kompare tests
diff --git a/kompare/tests/subversion/unifiedm.diff b/kompare/tests/subversion/unifiedm.diff
new file mode 100644
index 00000000..29a07705
--- /dev/null
+++ b/kompare/tests/subversion/unifiedm.diff
@@ -0,0 +1,173 @@
+Index: NEWS
+===================================================================
+--- NEWS
++++ NEWS 2002-09-22 14:34:37.000000000 +0200
+@@ -1 +1 @@
+-
++just a fake modif for kompare tests
+Index: README
+===================================================================
+--- README
++++ README 2002-09-13 23:05:48.000000000 +0200
+@@ -1,117 +1,47 @@
+- Vim KPart
+-
+-
+- by Philippe Fremy <pfremy@kde.com>
+-
+-
+-Okay, I made it : a Vim KPart!
+-
+-This means that you can have Vim embedded inside Konqueror, and everywhere a
+-text ReadWrite or ReadOnly KPart is requested. Actually, there is almost no
+-place right now where this is the case in KDE. KMail uses its own editor,
+-KDEvelop uses its own editor, Kate uses some more powerful Kate component.
+-
+-But this only the beginning. Enabling a part in those programs shouldn't be
+-much hassle and you can probably help me do it. My hope is really to get
+-KDevelop use Vim.
+-
+-
+-======= OBSOLETE ===========
+-Requirements:
+--------------
+-To make this KPart work, you need a graphicial Vim version 6 with the client-server stuff feature activated and with the vim60-vimpart-patch.diff applied. The patch is in this dir. I hope to get it into the main Vim tree. KVim has already the patch but is slightly less stable that the original GVim. A big advantage of KVim is that you get the native KDE dialogs when vim asks a question.
+-
+-
+-======= OBSOLETE ===========
+-Installation:
+--------------
+-To make your vimpart work, you'll have to go into the vimpart directory and run "testVim your_patched_vim". If the test does work, a file goodVim will be created. You will be able to install and use the component. Else, the test will report why it fails (features missing in vim).
+-
+-
+-
+-======= OBSOLETE ===========
+-Testing:
+---------
+-If you want to see your component without installing it, you can do the
+-following:
+-
+-1. configure, build. Then go into the Vimpart subdirectory.
+-
+-2. Include the current Vimpart directory in your KDEDIRS:
+-export KDEDIRS=`pwd`:$KDEDIR
+-
+-3. Symlink .libs to lib
+-ln -s .libs lib
+-
+-4. Create pseudo share/services dir:
+-mkdir share; mkdir share/services;
+-
+-5. Symlink to Vimpart.desktop:
+-ln -s Vimpart.desktop share/services/Vimpart.desktop
+-
+-6. Create a pseudo share/config dir
+-mkdir share/config;
+-
+-7. Symlink to vimwidgetrc
+-ln -s vimwidgetrc share/config/vimwidgetrc
+-
+-8. Update the desktop mimetype database:
+-kbuildsycoca
+-
+-To test it, run VimPartShell. Or run konqueror from this dir and click on a
+-text file.
+-
+-
+-======= OBSOLETE ===========
+-Remarks:
+---------
+-The initial preference of the Vim KPart is 10. Kate uses 8, so if you install the part, it will override Kate for all the mimetypes. You can always change that by manually editing the initial preference in the desktop file or by simply selecting which editor you prefer for which mimetype in the control center.
+-
+-If you find some mimetype not handled by the Vim KPart although they should be, send me a patch!
+-
+-
+-
+-How it works:
+--------------
+-At the beginning, we started to write KVim, a port of GVim to KDE to make
+-it possible to embed Vim inside KDE. But with the latest version of Vim, it
+-turns out that it is not necessary to have a native Vim.
+-
+-
+-I use QXembed, a widget which can embed any X application if it knows its X Window Id, using some X feature. The patch I provide will make vim displays its window id on stdout when the window is mapped. GVim 6.0 then provides a way to send commands to a Vim window from another process. If you look at the VimWidget source, you will see that 70% of the code is there to handle the communication process. The rest uses the communication channel to send the vim commands needed by kpart and ktexteditor.
+-
+-As far as I can tell, the part is race-condition free. If you issue many sendNormalCmd and many evalExpr, they are guaranted to be executed sequentially. This has caused me enough problems when it wasn't the case!
+-
+-
+-Qt, KDE2 and KDE3:
+-------------------
+-The VimWidget itself depends very litle on KDE. It is quite easy to port remove the KDE specific stuff, to use it in a Qt only program. In fact, at the beginning, it was only Qt-based.
+-
+-
+-
+-======= OBSOLETE ===========
+-Features & TODO:
+-----------------
+-I think most basic features required by an editor widget or part are supported. There are some possible improvement but I would like more feedback to know what really needs to be done. So don't hesitate to write me about your feelings using this.
+-
+-My TODO list is:
+-- restore the editing mode after sendCmd
+-- implement KTextEditor interface
+-- add some useful actions to the part (like search, ...)
+-
+-
+-
+-Feedback:
+----------
+-For the Vim KPart : pfremy@kde.com
+-For KVim: pfremy@kde.org, mikmak@freenux.org, orzel@kde.org
+-
+-
+-
+-
+-
+-
+-
++Yes, that's really a Vim Komponent :)
++Yes, you can have Vim inside KDE apps, you guessed it :)
+
++So, it's designed for KDE 3.x (if someone wants to port it to KDE 2 that
++should be easy), it uses GVim or KVim (even Motif Vim works) 6.x.
++It can be used in different apps :
++ - KDevelop (version 3)
++ - Konqueror (as a file viewer)
++ - KWrite
++ - KMail (coming in KDE 3.2)
++ - Kompare, KBabel ........ ;)
++
++CONFIGURATION
++=============
++once you compiled and installed it as any other app,
++start your KDE Control Center, go to the file manager section
++and open the Vim Component configuration module.
++Here, you have to select a Vim executable which may be found on
++your computer (generally /usr/bin/vim) will do it fine for most
++linux distributions. All you need is that it's a GUI-enabled Vim 6.0 or
++better.
++Push the test button, if that's okay then that's should be enough to start
++using it :)
++
++FUNCTIONMENT
++============
++Philippe Fremy (pfremy@kde.com) wrote the initial version of this kpart.
++The concept is to start a normal GUI Vim (like gvim), then "embeds" the Vim
++window into a KDE Widget.
++It used to be based on the ClientServer feature of Vim (type :help
++clientserver in Vim for more info) using external processus to control the
++embedded Vim. That was running quite fine, but was slow :/
++We changed that :)
++Now we communicate directly from the kpart to the embedded Vim thanks to X11
++without using externals processus. That's much faster and reliable ;)
++KVim has also another remote control system using KDE's DCOP communication
++backend.
++Currently I would advice people to use DCOP when running KVim and using X11
++communication with GVim (DCOP won't work with GVim anyway).
++There may be some differences in speed, though I have not noticed it here.
++The most important difference is that DCOP provides a signal system and that can
++make a difference to improve the interaction between KVim and the hosting
++application (KDevelop for example). But it's not yet used.
+
++Hope you'll enjoy Vim inside KDE :)
++Mickael "Mikmak" Marchand (marchand@kde.org)
+