Warning, file /sdk/kde-dev-scripts/kf5/convert-to-new-signal-slot-signal.pl was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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" );