File indexing completed on 2024-04-14 05:35:07

0001 #!/usr/bin/perl -w
0002 
0003 # Laurent Montel <montel@kde.org> (2014)
0004 # Convert to new signal/slot syntax
0005 # it's totally experimental
0006 # find -iname "*.cpp" |xargs kde-dev-scripts/kf5/convert-to-new-signal-slot-signal.pl
0007 
0008 use strict;
0009 use File::Basename;
0010 use lib dirname($0);
0011 use functionUtilkde;
0012 my $activateDebug = 1;
0013 my %varname = ();
0014 my $headerclassname;
0015 my $numberOfClassName=0;
0016 my %uiclassname = ();
0017 my %localuiclass = ();
0018 my %listOfClassName = ();
0019 my %overloadedSlots = ();
0020 my %privateSlots = ();
0021 my %privateVariableWithPointer = ();
0022 my $activateSlotPrivatePorting;
0023 
0024 sub rewriteConnectPrivateFunction($$$$$$$)
0025 {
0026     if (defined $activateSlotPrivatePorting) {
0027       my ($indent, $sender, $signal, $receiver, $slot, $slotArgument, $lastArgument) = @_;
0028       my $myNewLine;
0029       my $localSlotArgument;
0030       my $localSlotVariable;
0031       if ($slotArgument eq "()") {
0032           $localSlotArgument = "()";
0033           $localSlotVariable = "()";
0034       } elsif ($slotArgument eq "(QUrl)") {
0035           $localSlotArgument = "(const QUrl &url)";
0036           $localSlotVariable = "(url)";
0037       } elsif ($slotArgument eq "(KJob*)") {
0038           $localSlotArgument = "(KJob *job)";
0039           $localSlotVariable = "(job)";
0040       } else {
0041          return undef;
0042       }
0043       if (defined $lastArgument) {
0044          # lastArgument has ')'
0045          warn "last argument :$lastArgument\n";
0046          $myNewLine = $indent . "connect($sender, $signal, $receiver, [this]$localSlotArgument { d->$slot$localSlotVariable; }$lastArgument;\n";
0047       } else {
0048           $myNewLine = $indent . "connect($sender, $signal, $receiver, [this]$localSlotArgument { d->$slot$localSlotVariable; });\n";
0049       }
0050       return $myNewLine;
0051     }
0052     return undef;
0053 }
0054 
0055 sub rewriteConnectFunction($$$$$$)
0056 {
0057     my ($indent, $sender, $signal, $receiver, $slot, $lastArgument) = @_;
0058     my $myNewLine;
0059     if (defined $lastArgument) {
0060        # lastArgument has ')'
0061        warn "last argument :$lastArgument\n";
0062        $myNewLine = $indent . "connect($sender, $signal, $receiver, &$slot, $lastArgument;\n";
0063     } else {
0064        $myNewLine = $indent . "connect($sender, $signal, $receiver, &$slot);\n";
0065     }
0066 }
0067 
0068 
0069 # sets $_ if classname+function+arguments matches an overloaded signal (testSignal+testArguments)
0070 sub checkOverloadedSignal($$$$$)
0071 {
0072     my ($classname, $function, $arguments, $testSignal, $testArguments) = @_;
0073     my $initialArguments = $arguments; # hopefully includes the const-ref for a QString..
0074     my $initialTestArguments = $testArguments;
0075     $testArguments =~ s/const (.*)\s*&/$1/;
0076     $arguments =~ s/const (.*)\s*&/$1/;
0077     # Be sure to remove space. I don't understand why const (.*)\s*&/$1/; keeps space in $testArguments
0078     $testArguments =~ s, ,,g;
0079     if (($arguments eq $testArguments) and ($function eq $testSignal)) {
0080         $_ = "static_cast<void ($classname" . "::*)$initialTestArguments>(&" . "$classname" . "::$function)";
0081         print STDERR $_ . "\n";
0082     }
0083 }
0084 
0085 sub cast_overloaded_signal($$$)
0086 {
0087     my ($classname, $argument, $function) = @_;
0088     local $_;
0089     warn "ClassName \'$classname\' Argument \'$argument\' Function \'$function\'\n";
0090     if ($classname eq "QCompleter") {
0091         checkOverloadedSignal($classname, $function, $argument, "activated", "(const QString &)");
0092         checkOverloadedSignal($classname, $function, $argument, "activated", "(const QModelIndex &)");
0093         checkOverloadedSignal($classname, $function, $argument, "highlighted", "(const QString &)");
0094         checkOverloadedSignal($classname, $function, $argument, "highlighted", "(const QModelIndex &)");
0095 
0096     } elsif ($classname eq "KNotification") {
0097         checkOverloadedSignal($classname, $function, $argument, "activated", "(unsigned int)");
0098         checkOverloadedSignal($classname, $function, $argument, "activated", "(uint)");
0099     } elsif ($classname =~ /Combo/) {
0100         checkOverloadedSignal($classname, $function, $argument, "returnPressed", "()");
0101         checkOverloadedSignal($classname, $function, $argument, "returnPressed", "(const QString&)");
0102         checkOverloadedSignal($classname, $function, $argument, "activated", "(int)");
0103         checkOverloadedSignal($classname, $function, $argument, "activated", "(const QString &)");
0104         checkOverloadedSignal($classname, $function, $argument, "highlighted", "(int)");
0105         checkOverloadedSignal($classname, $function, $argument, "highlighted", "(const QString &)");
0106         checkOverloadedSignal($classname, $function, $argument, "currentIndexChanged", "(int)");
0107         checkOverloadedSignal($classname, $function, $argument, "currentIndexChanged", "(const QString &)");
0108     } elsif ($classname eq "QButtonGroup") {
0109         checkOverloadedSignal($classname, $function, $argument, "buttonReleased", "(QAbstractButton *)");
0110         checkOverloadedSignal($classname, $function, $argument, "buttonReleased", "(int)");
0111         checkOverloadedSignal($classname, $function, $argument, "buttonClicked", "(QAbstractButton *)");
0112         checkOverloadedSignal($classname, $function, $argument, "buttonClicked", "(int)");
0113         checkOverloadedSignal($classname, $function, $argument, "buttonPressed", "(QAbstractButton *)");
0114         checkOverloadedSignal($classname, $function, $argument, "buttonPressed", "(int)");
0115         checkOverloadedSignal($classname, $function, $argument, "buttonToggled", "(QAbstractButton *)");
0116         checkOverloadedSignal($classname, $function, $argument, "buttonToggled", "(int)");
0117     } elsif ( $classname =~ /QDoubleSpinBox/ ) {
0118         checkOverloadedSignal($classname, $function, $argument, "valueChanged", "(double)");
0119         checkOverloadedSignal($classname, $function, $argument, "valueChanged", "(const QString &)");
0120     } elsif (($classname =~ /SpinBox/) ) {
0121         checkOverloadedSignal($classname, $function, $argument, "valueChanged", "(int)");
0122         checkOverloadedSignal($classname, $function, $argument, "valueChanged", "(const QString &)");
0123     } elsif (($classname eq "KTabWidget") or ($classname =~ /Tab/)) { # has a virtual closeRequest(int) but that's not a signal
0124         checkOverloadedSignal($classname, $function, $argument, "closeRequest", "(QWidget *)");
0125     } elsif (($classname eq "KSelectAction") or ($classname eq "KFontAction")) {
0126         checkOverloadedSignal($classname, $function, $argument, "triggered", "(const QString &)");
0127         checkOverloadedSignal($classname, $function, $argument, "triggered", "(int)");
0128         #checkOverloadedSignal($function, $argument, "triggered", "(QAction \*)");
0129     } elsif ($classname eq "KUrlLabel") {
0130         checkOverloadedSignal($classname, $function, $argument, "leftClickedUrl", "(const QString &)");
0131         checkOverloadedSignal($classname, $function, $argument, "leftClickedUrl", "()");
0132         checkOverloadedSignal($classname, $function, $argument, "rightClickedUrl", "(const QString &)");
0133         checkOverloadedSignal($classname, $function, $argument, "rightClickedUrl", "()");
0134     } elsif ($classname eq "QTcpSocket") {
0135         checkOverloadedSignal($classname, $function, $argument, "error", "(QAbstractSocket::SocketError)");
0136         checkOverloadedSignal($classname, $function, $argument, "error", "()");
0137     } elsif ($classname eq "Akonadi::ChangeRecorder") {
0138         checkOverloadedSignal($classname, $function, $argument, "collectionChanged", "(const Akonadi::Collection &)");
0139         checkOverloadedSignal($classname, $function, $argument, "collectionChanged", "(const Akonadi::Collection &, const QSet<QByteArray &)");
0140     } elsif ($classname eq "KUrlRequester" ) {
0141         checkOverloadedSignal($classname, $function, $argument, "returnPressed", "(const QString &)");
0142         checkOverloadedSignal($classname, $function, $argument, "returnPressed", "()");
0143     } elsif ($classname eq "QNetworkReply" ) {
0144         checkOverloadedSignal($classname, $function, $argument, "error", "(QNetworkReply::NetworkError)");
0145     } elsif ($classname eq "QSignalMapper" ) {
0146         checkOverloadedSignal($classname, $function, $argument, "mapped", "(int)");
0147         checkOverloadedSignal($classname, $function, $argument, "mapped", "(QWidget *)");
0148         checkOverloadedSignal($classname, $function, $argument, "mapped", "(const QString &)");
0149         checkOverloadedSignal($classname, $function, $argument, "mapped", "(QObject *)");
0150     } elsif ($classname eq "KDirLister") {
0151         checkOverloadedSignal($classname, $function, $argument, "completed", "(const QUrl &)");
0152         checkOverloadedSignal($classname, $function, $argument, "completed", "()");
0153         checkOverloadedSignal($classname, $function, $argument, "clear", "(const QUrl &)");
0154         checkOverloadedSignal($classname, $function, $argument, "clear", "()");
0155         checkOverloadedSignal($classname, $function, $argument, "canceled", "(const QUrl &)");
0156         checkOverloadedSignal($classname, $function, $argument, "canceled", "()");
0157     } elsif (($classname eq "KProcess") || ($classname eq "QProcess" || $classname eq "KPtyProcess") ) {
0158         checkOverloadedSignal($classname, $function, $argument, "finished", "(int, QProcess::ExitStatus)");
0159         checkOverloadedSignal($classname, $function, $argument, "finished", "(int)");
0160         checkOverloadedSignal($classname, $function, $argument, "error", "(QProcess::ProcessError)");
0161     } elsif ($classname eq "KRatingWidget") {
0162         checkOverloadedSignal($classname, $function, $argument, "ratingChanged", "(int)");
0163         checkOverloadedSignal($classname, $function, $argument, "ratingChanged", "(unsigned int)");
0164         checkOverloadedSignal($classname, $function, $argument, "ratingChanged", "(uint)");
0165     }
0166 
0167     if ( defined $_ ) {
0168        return $_;
0169     } else {
0170        return "&" . "$classname" . "::" . "$function";
0171     }
0172 }
0173 
0174 # initialize variable before parsing a new file
0175 sub initVariables
0176 {
0177     %varname = ();
0178     $headerclassname = "";
0179     $numberOfClassName = 0;
0180     %uiclassname = ();
0181     %localuiclass = ();
0182     %listOfClassName = ();
0183     %overloadedSlots = ();
0184     %privateSlots = ();
0185     %privateVariableWithPointer = ();
0186 }
0187 
0188 # add new variable with its type.
0189 sub addToVarName($$$)
0190 {
0191     my ($classname, $var, $ref_localvarname) = @_;
0192     if (not $classname eq ":" and not $classname eq "return") {
0193       #If we found variable in header don't overwrite it
0194       #if (not defined $varname{$var}) {
0195           ${$ref_localvarname}{$var} = ${classname};
0196           warn "new variable added: \'$var\' className :\'$classname\'\n";
0197       #}
0198    }
0199 }
0200 
0201 # Clean sender variable
0202 sub cleanSender($)
0203 {
0204     my ($var) = @_;
0205     $var =~ s/^\(//;
0206     $var = functionUtilkde::cleanSpace($var);
0207     return $var;
0208 }
0209 
0210 # input: class::slot
0211 # output: notpossible string if this slot has default values
0212 sub checkOverloadedSlot($)
0213 {
0214     my ($fullslot) = @_;
0215     if (my ($class, $slot) = $fullslot =~ m/(.*)::([_\w]+)/) {
0216         return defined $overloadedSlots{$class}{$slot} ? "slot with default value(s)" : undef;
0217     }
0218     warn "Unparsable fullslot: $fullslot\n";
0219     return undef;
0220 }
0221 
0222 # input: class::slot
0223 # output: notpossible string if this slot is a Q_PRIVATE_SLOT
0224 sub checkPrivateSlot($)
0225 {
0226     my ($fullslot) = @_;
0227     if (my ($class, $slot) = $fullslot =~ m/(.*)::([_\w]+)/) {
0228         return defined $privateSlots{$class}{$slot} ? "slot is a Q_PRIVATE_SLOT" : undef;
0229     }
0230     warn "Unparsable fullslot: $fullslot\n";
0231     return undef;
0232 }
0233 
0234 # extract argument from signal
0235 sub extraArgumentFunctionName($)
0236 {
0237     my ($line) = @_;
0238     my $argument;
0239     warn "$line \n";
0240     my $regexpArgument = qr/
0241                     ^\(.*
0242                     ${functionUtilkde::paren_begin}1${functionUtilkde::paren_end}
0243                     \s*\).*$
0244                     /x; # /x Enables extended whitespace mode
0245     if ( my ($argument2) = $line =~ $regexpArgument) {
0246        $argument = $argument2;
0247     }
0248     return $argument;
0249 }
0250 
0251 # extract function name
0252 sub extractFunctionName($)
0253 {
0254     my ($line) = @_;
0255     my $regexpSignal = qr/
0256                     ^\(\s*
0257                     (\w+)                      # (1) functionname
0258                     .*$
0259                     /x; # /x Enables extended whitespace mode
0260     if ( my ($functionname) = $line =~ $regexpSignal) {
0261        $line = $1;
0262     }
0263     return $line;
0264 }
0265 
0266 # Parse the current line for variable declarations
0267 sub extraVariableFromLine($)
0268 {
0269     my ($file) = @_;
0270     if (/Ui::(\w+)\s+(\w+);/ || /Ui::(\w+)\s*\*\s*(\w+);/ || /Ui_(\w+)\s*\*\s*(\w+)/) {
0271         my $uiclass = $1;
0272         my $uivariable = $2;
0273         warn "$file: $uiclass :  $uivariable \n";
0274         if (defined $uiclassname{$uiclass}) {
0275             if (defined $activateDebug) {
0276                 warn "Found ui class \'$uiclass\' uivariable \'$uivariable\' \n";
0277             }
0278             $localuiclass{$uivariable} = $uiclass;
0279         }
0280     }
0281     # Foo toto;
0282     if ( /^\s*([:_\w]+)\s+([_\w]+);/) {
0283         my $classname = $1;
0284         my $var = $2;
0285         if ($classname ne "delete" and $classname ne "class" and $classname ne "struct" and $classname ne "return") {
0286             #print STDERR "CASE 1. classname='$classname'\n";
0287             addToVarName($classname, $var, \%varname);
0288         }
0289     }
0290 
0291     # Foo toto =
0292     if ( /^\s*([:_\w]+)\s+([_\w]+)\s*=/) {
0293         my $classname = $1;
0294         my $var = $2;
0295         #print STDERR "CASE 2. classname='$classname'\n";
0296         addToVarName($classname, $var, \%varname);
0297     }
0298     # Foo *toto =
0299     # Foo *const var =
0300     if ( /^\s*([:_\w]+)\s*\*\s*(?:const )?([_\w]+)\s*=/) {
0301         my $classname = $1;
0302         my $var = $2;
0303         #print STDERR "CASE 6. classname='$classname'\n";
0304         addToVarName($classname, $var, \%varname);
0305     }
0306 
0307     # Foo toto(...)
0308     # Unfortunately this also catches function declarations in header files, they look pretty much the same.
0309     # All we can do is filter out those that return void. But int a(5); and int a(int param); are not very different.
0310     if ( /^\s*([:_\w]+)\s+([_\w]+)\(/) {
0311         my $classname = $1;
0312         my $var = $2;
0313         if ($classname ne "else" and $classname ne "void") {
0314             #print STDERR "CASE 3. classname='$classname'\n";
0315             addToVarName($classname, $var, \%varname);
0316         }
0317     }
0318 
0319     # Private* d;
0320     # Private* const d;
0321     # AttachmentControllerBase *const q;
0322     if (/^\s*([:_\w]+)\s*\*\s*(?:const)?\s*([:_\w]+);/ ) {
0323         my $classname = $1;
0324         my $var = $2;
0325         #print STDERR "CASE 4. classname='$classname'\n";
0326         addToVarName($classname, $var, \%varname);
0327     }
0328     if (/^\s*QPointer\<\s*([:_\w]+)\s*\>\s*([:_\w]+);/ ) {
0329         my $classname = $1;
0330         my $var = $2;
0331         #print STDERR "CASE 5. classname='$classname'\n";
0332         if (not defined $privateVariableWithPointer{$var}) {
0333             if (defined $activateDebug) {
0334                 warn "Found private variable with QPointer class \'$classname\' variable \'$var\' \n";
0335             }
0336             $privateVariableWithPointer{$var} = $classname;
0337         }
0338     }
0339 }
0340 
0341 sub parseHeaderFile($)
0342 {
0343     my ($file) = @_;
0344     my $header = functionUtilkde::headerName($file);
0345     my $inslots = 0;
0346     if (!defined $header) {
0347        warn "no header found for file \'$file\'\n";
0348        return;
0349     } else {
0350        warn "Parse header file: $header \n";
0351     }
0352     # parse header file
0353     open(my $HEADERFILE, "<", $header) or warn "We can't open file $header:$!\n";
0354     my @lheader = map {
0355         my $orig = $_;
0356         my $regexp = qr/
0357            ^(\s*)                        # (1) Indentation
0358            ([:\w]+)                      # (2) Classname
0359            \*\s*                         #     *
0360            ([:\w]+)\s*                   # (3) variable name
0361            ;                             #     ;
0362            /x; # /x Enables extended whitespace mode
0363         if (my ($indent, $classname, $var) = $_ =~ $regexp) {
0364            $classname = functionUtilkde::cleanSpace($classname);
0365             if (defined $activateDebug) {
0366                warn "$header file: found classname \'$classname\' variable: \'$var\'\n";
0367            }
0368            $varname{$var} = ${classname};
0369         }
0370 
0371         # Search header class name
0372         if (/class\s*(?:\w+EXPORT|\w+DEPRECATED)?\s*(\w+)\s*:\s*public\s*(.*)/) {
0373            my $class = $1;
0374            my $parentClass = $2;
0375            if (defined $activateDebug) {
0376               warn "FOUND Class \'$class\' parentClass: \'$parentClass\' $_\n";
0377            }
0378            $headerclassname = $class;
0379            $overloadedSlots{$headerclassname} = ();
0380            $listOfClassName{$headerclassname} = 1;
0381            $numberOfClassName++;
0382         }
0383 
0384         # Parse slots, to detect overloads
0385         if (/^\s*(?:public|protected|private|signals|Q_SIGNALS)\s*(?:slots|Q_SLOTS)?\s*:/) {
0386             if (/slots/i) {
0387                 $inslots = 1;
0388             } else {
0389                 $inslots = 0;
0390             }
0391         }
0392         if ($inslots) {
0393             my $function_regexp = qr/
0394                ^(\s*)                                                         # (1) Indentation
0395                ([:\w]+)\s*                                                    # (2) Return type
0396                ([:\w]+)\s*                                                    # (3) Function name
0397                ${functionUtilkde::paren_begin}4${functionUtilkde::paren_end}  # (4) (args)
0398                /x; # /x Enables extended whitespace mode
0399             if (my ($indent, $return, $function, $args) = $_ =~ $function_regexp) {
0400                 if ($args =~ /=/) { # slot with default values
0401                     $overloadedSlots{$headerclassname}{$function} = 1;
0402                 }
0403             }
0404             # TODO also detect real overloads (seenSlots -> if already there, add to overloadedSlots)
0405         }
0406 
0407         #Q_PRIVATE_SLOT( d, void attachmentRemoved( MessageCore::AttachmentPart::Ptr ) )
0408 
0409         my $qprivateSlot = qr/
0410            ^(\s*)                        # (1) Indentation
0411            Q_PRIVATE_SLOT\s*\(\s*
0412            ([:\w]+)\s*                   # (2) private variable
0413            ,\s*([:\w]+)\s*               # (3) Return type
0414            ([:\w]+)\s*                   # (4) Function name
0415            ${functionUtilkde::paren_begin}5${functionUtilkde::paren_end}  # (5) (args)
0416 
0417            (.*)$                         # (6) afterreg
0418            /x; # /x Enables extended whitespace mode
0419         if (my ($indent, $privateVariable, $return, $function, $args, $after) = $_ =~ $qprivateSlot) {
0420            warn "found private slot  $args $_\n";
0421            $privateSlots{$headerclassname}{$function} = $args;
0422         }
0423 
0424         extraVariableFromLine($file);
0425 
0426         $_;
0427     } <$HEADERFILE>;
0428     warn "We have $numberOfClassName class in $header\n";
0429 }
0430 
0431 foreach my $file (@ARGV) {
0432 
0433     # 1) initialize variables before parsing files
0434     initVariables();
0435 
0436     # 2) Search all ui file and parse them
0437     functionUtilkde::extraVariableFromUiFile(\%varname, \%uiclassname);
0438 
0439     # 3) read header and parse it.
0440     parseHeaderFile($file);
0441 
0442     my $currentLine = 1;
0443 
0444     # 4) Parse cpp file
0445     my $modified;
0446     my $tojoin;
0447     my $toorig;
0448     my %varnamewithpointer = ();
0449     open(my $FILE, "<", $file) or warn "We can't open file $file:$!\n";
0450     my @l = map {
0451         my $orig = $_;
0452 
0453         # private class in cpp file.
0454         if (/Ui::(\w+)\s+(\w+);/ || /Ui::(\w+)\s*\*\s*(\w+);/ || /Ui_(\w+)\s*\*\s*(\w+)/) {
0455            my $uiclass = $1;
0456            my $uivariable = $2;
0457            warn "$file: $uiclass :  $uivariable \n";
0458            if (defined $uiclassname{$uiclass}) {
0459               if (defined $activateDebug) {
0460                  warn "Found ui class \'$uiclass\' uivariable \'$uivariable\' \n";
0461               }
0462               $localuiclass{$uivariable} = $uiclass;
0463            }
0464         }
0465 
0466         my $regexp = qr/
0467            ^(\s*)                        # (1) Indentation
0468            (.*?)                         # (2) Possibly "Classname *" (the ? means non-greedy)
0469            (\w+)                         # (3) variable name
0470            \s*=\s*                       #   assignment
0471            new\s+([:\w]+)                # (4) class name
0472            (.*)$                         # (5) afterreg
0473            /x; # /x Enables extended whitespace mode
0474         if (my ($indent, $left, $var, $classname, $afterreg) = $_ =~ $regexp) {
0475            $classname = functionUtilkde::cleanSpace($classname);
0476            $var = functionUtilkde::cleanSpace($var);
0477            #If we found variable in header don't overwrite it
0478            if (not defined $varname{$var} and not defined $privateVariableWithPointer{$var}) {
0479                 if (defined $activateDebug) {
0480                    warn "$file: cpp file: found classname \'$classname\' variable: \'$var\' $_\n";
0481                 }
0482                 if ( $left =~ /QPointer\<$classname\>/) {
0483                    $varnamewithpointer{$var} = ${classname};
0484                 } else {
0485                    $varname{$var} = ${classname};
0486                 }
0487            }
0488         }
0489         if (/(\w+)\s*\*\s*(\w+)\s*=.*addAction\s*\(/) {
0490            my $classname = $1;
0491            my $var = $2;
0492            addToVarName($classname, $var, \%varname);
0493         }
0494 
0495         #QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0496         if (/(\w+)\s*\*\s*(\w+)\s*=.*buttonBox\-\>button\s*\(QDialogButtonBox\b/) {
0497            my $classname = $1;
0498            my $var = $2;
0499            addToVarName($classname, $var, \%varname);
0500         }
0501 
0502         extraVariableFromLine($file);
0503 
0504 
0505         if ( /^\s*([:\w]+)::([~\w]+).*/ ) {
0506             my $currentClass = $1;
0507             my $currentFunctionName = $2;
0508             #warn "We are in a constructor: currentClass: \'$currentClass\', function name \'$currentFunctionName\'\n";
0509             if (defined $listOfClassName{$currentClass}) {
0510                 #warn "it's an header class\n";
0511                 $headerclassname = $currentClass;
0512             }
0513 
0514         } elsif ( /^([:\w]+)\s*\*\s*(\w+)::([~\w]+)\.*/ || /^([:\w]+)\s*(\w+)::([~\w]+)\.*/) {
0515             my $currentClass = $2;
0516             my $currentFunctionName = $3;
0517             my $currentReturnFunction = $1;
0518             #warn "We are in a function : currentClass: \'$currentClass\', function name \'$currentFunctionName\', return type \'$currentReturnFunction\'\n";
0519             if (defined $listOfClassName{$currentClass}) {
0520                 #warn "it's an header class\n";
0521                 $headerclassname = $currentClass;
0522             }
0523         } elsif ( /^\s*class ([:\w]+)/) {
0524             # class defined in the .cpp file
0525             $headerclassname = $1;
0526             $listOfClassName{$headerclassname} = 1;
0527         }
0528 
0529         # Verify comment
0530         if ( defined $tojoin) {
0531 
0532            $toorig .= $_;
0533 
0534            $tojoin =~ s/\s*\n$//; # remove any trailing space
0535            $_ =~ s/^\s*/ /; # replace indent with single space
0536            $_ = $tojoin . $_;
0537            warn "look at end ? \'$_\'\n";
0538            if ( /;\s*$/ || /;\s*\/\*\.*\*\// || /;\s*\n$/) {
0539              undef $tojoin;
0540            }
0541         }
0542 
0543         my $regexpConnect = qr/
0544           ^(\s*(?:[\-\>:\w]+)?)           # (1) Indentation, optional classname or variable name
0545           connect\s*
0546           ${functionUtilkde::paren_begin}2${functionUtilkde::paren_end}  # (2) (args)
0547           ;/x; # /x Enables extended whitespace mode
0548         if (my ($indent, $argument) = $_ =~ $regexpConnect ) {
0549            if (defined $activateDebug) {
0550               warn "ARGUMENT $argument\n";
0551            }
0552            my ($sender, $signal, $receiver, $signalorslot, $slot, $lastArgument, $after);
0553            my $connectArgument_regexp = qr/
0554                                  ^([^,]*)\s*                 # (1) sender
0555                                  ,\s*SIGNAL\s*${functionUtilkde::paren_begin}2${functionUtilkde::paren_end}\s*     # (2) signal
0556                                  ,\s*([^,]*)                 # (3) receiver
0557                                  ,\s*(\w+)\s*                # (4) SLOT or SIGNAL
0558                                  ${functionUtilkde::paren_begin}5${functionUtilkde::paren_end}          # (5) slot
0559                                  (?:,\s([^,]*))?             # (6) Last argument in slot as Qt::QueuedConnection
0560                                  (.*)$                       # (7) after
0561                                  /x;
0562            if ( ($sender, $signal, $receiver, $signalorslot, $slot, $lastArgument, $after) = $argument =~ $connectArgument_regexp) {
0563 
0564               # We can have SIGNAL/SIGNAL or SIGNAL/SLOT
0565               if (($signalorslot eq "SIGNAL") or ($signalorslot eq "SLOT")) {
0566                 warn "11Without arguments: SENDER: \'$sender\'  SIGNAL: \'$signal\' RECEIVER: \'$receiver\' SLOT: \'$slot\' \n";
0567                 $sender = cleanSender($sender);
0568                 my $signalArgument = extraArgumentFunctionName($signal);
0569                 $signal = extractFunctionName($signal);
0570                 my $slotArgument = extraArgumentFunctionName($slot);
0571                 $slot = extractFunctionName($slot);
0572                 my $originalSlot = $slot;
0573                 my $localSenderVariable;
0574                 my $localReceiverVariable;
0575                 if ( $sender =~ /^&/) {
0576                    $sender =~ s/^&//;
0577                    $localSenderVariable = 1;
0578                 }
0579                 if ( $receiver =~ /^&/) {
0580                    $receiver =~ s/^&//;
0581                    $localReceiverVariable = 1;
0582                 }
0583 
0584                 my $notpossible;
0585                 my $isPrivateSlot;
0586                 if ( (defined $varname{$sender}) and (defined $varname{$receiver}) ) {
0587                     $signal = cast_overloaded_signal($varname{$sender}, $signalArgument, $signal);
0588                     $slot = "$varname{$receiver}" . "::" . "$slot";
0589                     if ( defined $localSenderVariable) {
0590                        $sender = "&" . $sender;
0591                     }
0592                     if ( defined $localReceiverVariable) {
0593                        $receiver = "&" . $receiver;
0594                     }
0595                     if (not defined $notpossible) {
0596                         $notpossible = checkOverloadedSlot($slot);
0597                     }
0598                     if (not defined $notpossible) {
0599                         $isPrivateSlot = checkPrivateSlot($slot);
0600                     }
0601                     if (not defined $notpossible) {
0602                         if (not defined $isPrivateSlot) {
0603                             $_ = rewriteConnectFunction($indent, $sender, $signal, $receiver, $slot, $lastArgument);
0604                         } else {
0605                             my $localChanges = rewriteConnectPrivateFunction($indent, $sender, $signal, $receiver, $originalSlot, $slotArgument, $lastArgument);
0606                             if (defined $localChanges) {
0607                                 $_ = $localChanges;
0608                             }
0609                         }
0610                         undef $toorig;
0611                     }
0612                 } else {
0613                   my $classWithQPointer;
0614                   my $receiverWithQPointer;
0615                   if ( defined $varname{$sender} ) {
0616                     $signal = cast_overloaded_signal($varname{$sender}, $signalArgument, $signal);
0617                   } elsif ( defined $privateVariableWithPointer{$sender} ) {
0618                     $signal = cast_overloaded_signal($privateVariableWithPointer{$sender}, $signalArgument, $signal);
0619                     $classWithQPointer = 1;
0620                   } elsif ( defined $varnamewithpointer{$sender} ) {
0621                     $signal = cast_overloaded_signal($varnamewithpointer{$sender}, $signalArgument, $signal);
0622                     $classWithQPointer = 1;
0623                   } elsif ( $sender eq "this") {
0624                     if ( $headerclassname eq "" ) {
0625                        $notpossible = "sender is 'this' but I don't know the current classname";
0626                     }
0627                     $signal = cast_overloaded_signal($headerclassname, $signalArgument, $signal);
0628                   } elsif ( $sender eq "qApp") {
0629                      $signal = "&QApplication::$signal";
0630                   } elsif ( $sender eq "kapp") {
0631                      $signal = "&KApplication::$signal";
0632                   } elsif ( $sender =~ /button\(QDialogButtonBox::/) {
0633                     $signal = "&QPushButton::$signal";
0634                   } elsif ( $sender =~ /actionCollection\(\)\-\>action\b/) {
0635                     $signal = "&QAction::$signal";
0636                   } elsif ( $sender =~ /(.*)::self\(\)/) {
0637                     my $class = $1;
0638                     $signal = "&" . "$class" . "::" . "$signal";
0639                   } else {
0640                     # It's not specific to ui class. It can be a private class too
0641                     if ( $sender =~ /(\w+)\.(.*)/  || $sender =~ /(\w+)\-\>(.*)/) {
0642                        my $uivariable = $1;
0643                        my $varui = $2;
0644                        if (defined $activateDebug) {
0645                           warn "22UI VARIABLE :$uivariable\n";
0646                        }
0647                        if (defined $localuiclass{$uivariable} ) {
0648                            if (defined $activateDebug) {
0649                               warn "variable defined  $varui\n";
0650                            }
0651                            if ( defined $varname{$varui} ) {
0652                               if (defined $activateDebug) {
0653                                  warn "vartype found $varname{$varui} \n";
0654                               }
0655                               $signal = cast_overloaded_signal($varname{$varui}, $signalArgument, $signal);
0656                            } else {
0657                              $notpossible = "unknown variable $varui";
0658                            }
0659                        } elsif (defined $varname{$uivariable}) {
0660                            if ( defined $varname{$varui} ) {
0661                               $signal = cast_overloaded_signal($varname{$varui}, $signalArgument, $signal);
0662 
0663                               if (defined $activateDebug) {
0664                                  warn "vartype found $varname{$varui} \n";
0665                               }
0666                            } else {
0667                              $notpossible = "unknown variable $varui";
0668                            }
0669                        } else {
0670                          $notpossible = "unknown variable $uivariable";
0671                        }
0672                     } else {
0673                        $notpossible = "unparsed sender $sender";
0674                     }
0675                   }
0676                   if (not defined $notpossible) {
0677 
0678                     if ( defined $varname{$receiver} ) {
0679                       $slot = "$varname{$receiver}::$slot";
0680                     } elsif ( defined $varnamewithpointer{$receiver} ) {
0681                       $slot = "$varnamewithpointer{$receiver}" . "::" ." $slot";
0682                       $receiverWithQPointer = 1;
0683                     } elsif ( defined $privateVariableWithPointer{$receiver} ) {
0684                       $slot = "$privateVariableWithPointer{$receiver}" . "::". "$slot";
0685                       $receiverWithQPointer = 1;
0686                     } elsif ( $receiver eq "this") {
0687                       if ( $headerclassname eq "" ) {
0688                          $notpossible = "no current classname";
0689                       }
0690                       $slot = "$headerclassname" . "::" . "$slot";
0691                     } else {
0692                        if ( $receiver =~ /(\w+)\.(.*)/  || $receiver =~ /(\w+)\-\>(.*)/) {
0693                           my $uivariable = $1;
0694                           my $varui = $2;
0695                           if (defined $activateDebug) {
0696                              warn "11UI VARIABLE :$uivariable\n";
0697                           }
0698                           if (defined $localuiclass{$uivariable} ) {
0699                               if (defined $activateDebug) {
0700                                   warn "variable defined  $varui\n";
0701                               }
0702                               if ( defined $varname{$varui} ) {
0703                                   if (defined $activateDebug) {
0704                                       warn "vartype found $varname{$varui} \n";
0705                                  }
0706                                  $slot = "$varname{$varui}" . "::" ." $slot";
0707                               } else {
0708                                  $notpossible = "unknown variable $varui";
0709                               }
0710                           } else {
0711                              $notpossible = "no class for $uivariable";
0712                           }
0713                        } else {
0714                            $notpossible = "receiver $receiver is unknown";
0715                        }
0716                     }
0717                   }
0718                   if (not defined $notpossible) {
0719                       $notpossible = checkOverloadedSlot($slot);
0720                   }
0721                   if (not defined $notpossible) {
0722                       $isPrivateSlot = checkPrivateSlot($slot);
0723                   }
0724 
0725                   if (not defined $notpossible) {
0726                      if ( defined $localSenderVariable) {
0727                          $sender = "&" . $sender;
0728                      }
0729                      if ( defined $localReceiverVariable) {
0730                          $receiver = "&" . $receiver;
0731                      }
0732                      if ( defined $classWithQPointer) {
0733                          $sender .= ".data()";
0734                      }
0735                      if (defined $receiverWithQPointer) {
0736                          $receiver .= ".data()";
0737                      }
0738                      if (not defined $isPrivateSlot) {
0739                          $_ = rewriteConnectFunction($indent, $sender, $signal, $receiver, $slot, $lastArgument);
0740                      } else {
0741                          my $localChanges = rewriteConnectPrivateFunction($indent, $sender, $signal, $receiver, $originalSlot, $slotArgument, $lastArgument);
0742                          if (defined $localChanges) {
0743                             $_ = $localChanges;
0744                          }
0745                      }
0746                      undef $toorig;
0747                   } else {
0748                        my $line = $_;
0749                        chomp $line;
0750                        warn "$file : line $currentLine : Can not convert \'$line\' because $notpossible\n";
0751                        if (defined $toorig) {
0752                            $_ = $toorig;
0753                            undef $toorig;
0754                        }
0755                   }
0756                 }
0757 
0758                 if (defined $activateDebug) {
0759                     warn "AFTER Without arguments: SENDER: \'$sender\'  SIGNAL: \'$signal\' RECEIVER: \'$receiver\' SLOT: \'$slot\' \n";
0760                 }
0761               }
0762            } else {
0763                 my $connectArgument2_regexp = qr/
0764                                  ^([^,]*)\s*                                                       # (1) sender
0765                                  \s*,\s*SIGNAL\s*
0766                                  ${functionUtilkde::paren_begin}2${functionUtilkde::paren_end}     # (2) signal
0767                                  ,\s*(\w+)\s*                                                      # (3) SLOT or SIGNAL
0768                                  ${functionUtilkde::paren_begin}4${functionUtilkde::paren_end}     # (4) slot
0769                                  (?:,\s([^,]*))?                                                   # (5) Last argument in slot as Qt::QueuedConnection
0770                                  (.*)$                                                             # (6) after
0771                                  /x;
0772                 if ( ($sender, $signal, $signalorslot, $slot, $lastArgument, $after) = $argument =~ $connectArgument2_regexp) {
0773                    # We can have SIGNAL/SIGNAL or SIGNAL/SLOT
0774                    if (($signalorslot eq "SIGNAL") or ($signalorslot eq "SLOT")) {
0775 
0776                      $sender = cleanSender($sender);
0777                      my $signalArgument = extraArgumentFunctionName($signal);
0778                      $signal = extractFunctionName($signal);
0779                      my $slotArgument = extraArgumentFunctionName($slot);
0780                      $slot = extractFunctionName($slot);
0781                      my $localVariable;
0782                      my $originalSlot = $slot;
0783                      if ( $sender =~ /^&/) {
0784                        $sender =~ s/^&//;
0785                        $localVariable = 1;
0786                      }
0787                      my $privateClass;
0788                      if ( $sender =~ /^d\-\>/) {
0789                        $sender =~ s/^d\-\>//;
0790                        $privateClass = 1;
0791                      }
0792                      if (defined $activateDebug) {
0793                         warn "With Argument and no receiver: SENDER: \'$sender\'  SIGNAL: \'$signal\' SLOT: \'$slot\' \n";
0794                      }
0795 
0796                      # => we don't have receiver => slot and signal will have same parent.
0797                      my $notpossible;
0798                      my $isPrivateSlot;
0799 
0800                      if ( $headerclassname eq "" ) {
0801                         $notpossible = "no current classname";
0802                      }
0803                      if ( defined $varname{$sender} ) {
0804                         $slot = "$headerclassname" . "::" . "$slot";
0805                         $signal = cast_overloaded_signal($varname{$sender}, $signalArgument, $signal);
0806                      } else {
0807                         $slot = "$headerclassname" . "::" . "$slot";
0808                         if ( $sender eq "this") {
0809                             $signal = cast_overloaded_signal($headerclassname, $signalArgument, $signal);
0810                         } elsif ( $sender eq "qApp") {
0811                           $signal = "&QApplication::$signal";
0812                         } elsif ( $sender eq "kapp") {
0813                           $signal = "&KApplication::$signal";
0814                         } elsif ( $sender =~ /button\(QDialogButtonBox::/) {
0815                           $signal = "&QPushButton::$signal";
0816                         } elsif ( $sender =~ /actionCollection\(\)\-\>action\b/) {
0817                            $signal = "&QAction::$signal";
0818                         } elsif ( $sender =~ /(.*)::self\(\)/) {
0819                           my $class = "&" . $1;
0820                           $signal = "$class" . "::" . "$signal";
0821                         } else {
0822                             if ( $sender =~ /(\w+)\.(.*)/  || $sender =~ /(\w+)\-\>(.*)/) {
0823                               my $uivariable = $1;
0824                               my $varui = $2;
0825                               if (defined $activateDebug) {
0826                                  warn "With Argument and no receiver: UI VARIABLE :$uivariable: variable name :$varui\n";
0827                               }
0828                               if (defined $localuiclass{$uivariable} ) {
0829                                 if (defined $activateDebug) {
0830                                    warn "With Argument and no receiver: variable defined  $varui\n";
0831                                 }
0832 
0833                                 if ( defined $varname{$varui} ) {
0834                                    $signal = cast_overloaded_signal($varname{$varui}, $signalArgument, $signal);
0835 
0836                                   warn "vartype found $varname{$varui} \n";
0837                                 } else {
0838                                   $notpossible = "unknown variable $varui";
0839                                 }
0840                               } else {
0841                                 $notpossible = "unknown class for $uivariable";
0842                               }
0843                             } else {
0844                                 $notpossible = "unparsed sender $sender";
0845                             }
0846                         }
0847                       }
0848                       if (not defined $notpossible) {
0849                           $notpossible = checkOverloadedSlot($slot);
0850                       }
0851                       if (not defined $notpossible) {
0852                           $isPrivateSlot = checkPrivateSlot($slot);
0853                       }
0854                       if (not defined $notpossible) {
0855                         if ( defined $privateClass ) {
0856                             $sender = "d->" . $sender;
0857                         }
0858                         if ( defined $localVariable) {
0859                             $sender = "&" . $sender;
0860                         }
0861                         my $receiver = "this";
0862                         if (not defined $isPrivateSlot) {
0863                             $_ = rewriteConnectFunction($indent, $sender, $signal, $receiver, $slot, $lastArgument);
0864                         } else {
0865                             my $localChanges = rewriteConnectPrivateFunction($indent, $sender, $signal, $receiver, $originalSlot, $slotArgument, $lastArgument);
0866                             if (defined $localChanges) {
0867                                 $_ = $localChanges;
0868                             }
0869                         }
0870                         undef $toorig;
0871                       } else {
0872                          my $line = $_;
0873                          chomp $line;
0874                          warn "$file : line $currentLine : Can not convert \'$line\' because $notpossible\n";
0875                          if (defined $toorig) {
0876                               $_ = $toorig;
0877                               undef $toorig;
0878                          }
0879                       }
0880                   }
0881               }
0882            }
0883            undef $toorig;
0884         } else {
0885           if ( /^(\s*(?:[\-\>:\w]+)?)\bconnect\b\s*/) {
0886              warn "It's perhaps a multi line " . $_ . "\n";
0887              $tojoin = $_;
0888              $toorig = $_;
0889              $_ = "";
0890           }
0891         }
0892         $currentLine++;
0893         $modified ||= $orig ne $_;
0894         $_;
0895     } <$FILE>;
0896 
0897     if ($modified) {
0898         open (my $OUT, ">", $file);
0899         print $OUT @l;
0900         close ($OUT);
0901     }
0902 }
0903 
0904 functionUtilkde::diffFile( "@ARGV" );