diff --git a/scripts/sipify.pl b/scripts/sipify.pl index f475360cc66..a38d36a22d8 100755 --- a/scripts/sipify.pl +++ b/scripts/sipify.pl @@ -21,7 +21,7 @@ my $headerfile = $ARGV[0]; # read file open(my $handle, "<", $headerfile) || die "Couldn't open '".$headerfile."' for reading because: ".$!; -chomp(my @lines = <$handle>); +chomp(my @INPUT_LINES = <$handle>); close $handle; # config @@ -36,46 +36,66 @@ my @ACCESS = (PUBLIC); my @CLASSNAME = (); my @EXPORTED = (0); my $MULTILINE_DEFINITION = 0; +my $ACTUAL_CLASS = ''; -my $comment = ''; -my $global_ifdef_nesting_index = 0; -my @global_bracket_nesting_index = (0); -my $private_section_line = ''; -my $return_type = ''; -my $is_override = 0; -my %qflag_hash; +my $COMMENT = ''; +my $GLOB_IFDEF_NESTING_IDX = 0; +my @GLOB_BRACKET_NESTING_IDX = (0); +my $PRIVATE_SECTION_LINE = ''; +my $RETURN_TYPE = ''; +my $IS_OVERRIDE = 0; +my %QFLAG_HASH; -my $line_count = @lines; -my $line_idx = 0; -my $line; -my @output = (); +my $LINE_COUNT = @INPUT_LINES; +my $LINE_IDX = 0; +my $LINE; +my @OUTPUT = (); -push @output, "/************************************************************************\n"; -push @output, " * This file has been generated automatically from *\n"; -push @output, " * *\n"; -push @output, sprintf " * %-*s *\n", 68, $headerfile; -push @output, " * *\n"; -push @output, " * Do not edit manually ! Edit header and run scripts/sipify.pl again *\n"; -push @output, " ************************************************************************/\n"; -# write some code in front of line to know where the output comes from -$debug == 0 or push @output, "CODE SIP_RUN MultiLine\n"; -sub dbg -{ - my $msg = ''; - $debug == 0 or $msg = sprintf("%d %-4s %-1d %-1d ", $line_idx, $_[0], $SIP_RUN, $MULTILINE_DEFINITION); - return $msg; -} -sub dbg_info -{ - if ($debug == 1){ - push @output, $_[0]."\n"; - print $line_idx." ".@ACCESS." ".$SIP_RUN." ".$MULTILINE_DEFINITION." ".$_[0]."\n"; - } +sub read_line { + my $new_line = $INPUT_LINES[$LINE_IDX]; + $LINE_IDX++; + $debug == 0 or print sprintf('LIN:%d DEPTH:%d ACC:%d BRCK:%d SIP:%d MLT:%d CLSS: %s/%d', + $LINE_IDX, + $#ACCESS, + $ACCESS[$#ACCESS], + $GLOB_BRACKET_NESTING_IDX[$#GLOB_BRACKET_NESTING_IDX], + $SIP_RUN, + $MULTILINE_DEFINITION, + $ACTUAL_CLASS, + $#CLASSNAME)." :: ".$new_line."\n"; + return $new_line; } -sub processDoxygenLine -{ +sub write_output { + my ($dbg_code, $out) = @_; + if ($debug == 1){ + $dbg_code = sprintf("%d %-4s :: ", $LINE_IDX, $dbg_code); + } + else{ + $dbg_code = ''; + } + push @OUTPUT, $dbg_code.$out; +} + +sub dbg_info { + if ($debug == 1){ + push @OUTPUT, $_[0]."\n"; + print $LINE_IDX." ".@ACCESS." ".$SIP_RUN." ".$MULTILINE_DEFINITION." ".$_[0]."\n"; + } +} + +sub write_header_footer { + push @OUTPUT, "/************************************************************************\n"; + push @OUTPUT, " * This file has been generated automatically from *\n"; + push @OUTPUT, " * *\n"; + push @OUTPUT, sprintf " * %-*s *\n", 68, $headerfile; + push @OUTPUT, " * *\n"; + push @OUTPUT, " * Do not edit manually ! Edit header and run scripts/sipify.pl again *\n"; + push @OUTPUT, " ************************************************************************/\n"; +} + +sub processDoxygenLine { my $line = $_[0]; # remove \a formatting $line =~ s/\\a (.+?)\b/``$1``/g; @@ -107,13 +127,13 @@ sub processDoxygenLine sub detect_and_remove_following_body_or_initializerlist { # https://regex101.com/r/ZaP3tC/6 do {no warnings 'uninitialized'; - if ( $line =~ m/^(\s*)?((?:(?:explicit|static|const|unsigned|virtual)\s+)*)(([\w:]+(<.*?>)?\s+[*&]?)?(~?\w+|(\w+::)?operator.{1,2})\s*\(([\w=()\/ ,&*<>."-]|::)*\)( (?:const|SIP_[A-Z_]*?))*)\s*((\s*[:,]\s+\w+\(.*\))*\s*\{.*\};?|(?!;))(\s*\/\/.*)?$/ - || $line =~ m/SIP_SKIP\s*(?!;)\s*(\/\/.*)?$/ - || $line =~ m/^\s*class.*SIP_SKIP/ ){ + if ( $LINE =~ m/^(\s*)?((?:(?:explicit|static|const|unsigned|virtual)\s+)*)(([\w:]+(<.*?>)?\s+[*&]?)?(~?\w+|(\w+::)?operator.{1,2})\s*\(([\w=()\/ ,&*<>."-]|::)*\)( (?:const|SIP_[A-Z_]*?))*)\s*((\s*[:,]\s+\w+\(.*\))*\s*\{.*\};?|(?!;))(\s*\/\/.*)?$/ + || $LINE =~ m/SIP_SKIP\s*(?!;)\s*(\/\/.*)?$/ + || $LINE =~ m/^\s*class.*SIP_SKIP/ ){ dbg_info("remove constructor definition, function bodies, member initializing list"); my $newline = "$1$2$3;"; - remove_following_body_or_initializerlist() unless $line =~ m/{.*}(\s*SIP_\w+)*\s*(\/\/.*)?$/; - $line = $newline; + remove_following_body_or_initializerlist() unless $LINE =~ m/{.*}(\s*SIP_\w+)*\s*(\/\/.*)?$/; + $LINE = $newline; } }; } @@ -121,24 +141,21 @@ sub detect_and_remove_following_body_or_initializerlist { sub remove_following_body_or_initializerlist { do {no warnings 'uninitialized'; dbg_info("remove constructor definition, function bodies, member initializing list"); - $line = $lines[$line_idx]; - $line_idx++; - while ( $line =~ m/^\s*[:,]\s+([\w<>]|::)+\(.*?\)/){ + $LINE = read_line(); + while ( $LINE =~ m/^\s*[:,]\s+([\w<>]|::)+\(.*?\)/){ dbg_info(" member initializing list"); - $line = $lines[$line_idx]; - $line_idx++; + $LINE = read_line(); } - if ( $line =~ m/^\s*\{/ ){ + if ( $LINE =~ m/^\s*\{/ ){ my $nesting_index = 0; - while ($line_idx < $line_count){ + while ($LINE_IDX < $LINE_COUNT){ dbg_info(" remove body"); - $nesting_index += $line =~ tr/\{//; - $nesting_index -= $line =~ tr/\}//; + $nesting_index += $LINE =~ tr/\{//; + $nesting_index -= $LINE =~ tr/\}//; if ($nesting_index == 0){ last; } - $line = $lines[$line_idx]; - $line_idx++; + $LINE = read_line(); } } }; @@ -146,40 +163,40 @@ sub remove_following_body_or_initializerlist { sub fix_annotations(){ # printed annotations - $line =~ s/\bSIP_ABSTRACT\b/\/Abstract\//; - $line =~ s/\bSIP_ARRAY\b/\/Array\//g; - $line =~ s/\bSIP_ARRAYSIZE\b/\/ArraySize\//g; - $line =~ s/\bSIP_DEPRECATED\b/\/Deprecated\//g; - $line =~ s/\bSIP_CONSTRAINED\b/\/Constrained\//g; - $line =~ s/\bSIP_EXTERNAL\b/\/External\//g; - $line =~ s/\bSIP_FACTORY\b/\/Factory\//; - $line =~ s/\bSIP_IN\b/\/In\//g; - $line =~ s/\bSIP_INOUT\b/\/In,Out\//g; - $line =~ s/\bSIP_KEEPREFERENCE\b/\/KeepReference\//; - $line =~ s/\bSIP_NODEFAULTCTORS\b/\/NoDefaultCtors\//; - $line =~ s/\bSIP_OUT\b/\/Out\//g; - $line =~ s/\bSIP_RELEASEGIL\b/\/ReleaseGIL\//; - $line =~ s/\bSIP_TRANSFER\b/\/Transfer\//g; - $line =~ s/\bSIP_TRANSFERBACK\b/\/TransferBack\//; - $line =~ s/\bSIP_TRANSFERTHIS\b/\/TransferThis\//; + $LINE =~ s/\bSIP_ABSTRACT\b/\/Abstract\//; + $LINE =~ s/\bSIP_ARRAY\b/\/Array\//g; + $LINE =~ s/\bSIP_ARRAYSIZE\b/\/ArraySize\//g; + $LINE =~ s/\bSIP_DEPRECATED\b/\/Deprecated\//g; + $LINE =~ s/\bSIP_CONSTRAINED\b/\/Constrained\//g; + $LINE =~ s/\bSIP_EXTERNAL\b/\/External\//g; + $LINE =~ s/\bSIP_FACTORY\b/\/Factory\//; + $LINE =~ s/\bSIP_IN\b/\/In\//g; + $LINE =~ s/\bSIP_INOUT\b/\/In,Out\//g; + $LINE =~ s/\bSIP_KEEPREFERENCE\b/\/KeepReference\//; + $LINE =~ s/\bSIP_NODEFAULTCTORS\b/\/NoDefaultCtors\//; + $LINE =~ s/\bSIP_OUT\b/\/Out\//g; + $LINE =~ s/\bSIP_RELEASEGIL\b/\/ReleaseGIL\//; + $LINE =~ s/\bSIP_TRANSFER\b/\/Transfer\//g; + $LINE =~ s/\bSIP_TRANSFERBACK\b/\/TransferBack\//; + $LINE =~ s/\bSIP_TRANSFERTHIS\b/\/TransferThis\//; - $line =~ s/SIP_PYNAME\(\s*(\w+)\s*\)/\/PyName=$1\//; + $LINE =~ s/SIP_PYNAME\(\s*(\w+)\s*\)/\/PyName=$1\//; # combine multiple annotations # https://regex101.com/r/uvCt4M/3 do {no warnings 'uninitialized'; - $line =~ s/\/(\w+(=\w+)?)\/\s*\/(\w+(=\w+)?)\//\/$1,$3\//; + $LINE =~ s/\/(\w+(=\w+)?)\/\s*\/(\w+(=\w+)?)\//\/$1,$3\//; (! $3) or dbg_info("combine multiple annotations -- works only for 2"); }; # unprinted annotations - $line =~ s/(\w+)(\<(?>[^<>]|(?2))*\>)?\s+SIP_PYTYPE\(\s*\'?([^()']+)(\(\s*(?:[^()]++|(?2))*\s*\))?\'?\s*\)/$3/g; - $line =~ s/=\s+[^=]*?\s+SIP_PYARGDEFAULT\(\s*\'?([^()']+)(\(\s*(?:[^()]++|(?2))*\s*\))?\'?\s*\)/= $1/g; + $LINE =~ s/(\w+)(\<(?>[^<>]|(?2))*\>)?\s+SIP_PYTYPE\(\s*\'?([^()']+)(\(\s*(?:[^()]++|(?2))*\s*\))?\'?\s*\)/$3/g; + $LINE =~ s/=\s+[^=]*?\s+SIP_PYARGDEFAULT\(\s*\'?([^()']+)(\(\s*(?:[^()]++|(?2))*\s*\))?\'?\s*\)/= $1/g; # remove argument - if ($line =~ m/SIP_PYARGREMOVE/){ + if ($LINE =~ m/SIP_PYARGREMOVE/){ dbg_info("remove arg"); if ( $MULTILINE_DEFINITION == 1 ){ - my $prev_line = pop(@output) =~ s/\n$//r; + my $prev_line = pop(@OUTPUT) =~ s/\n$//r; # update multi line status my $parenthesis_balance = 0; $parenthesis_balance += $prev_line =~ tr/\(//; @@ -188,13 +205,13 @@ sub fix_annotations(){ $MULTILINE_DEFINITION = 0; } # concat with above line to bring previous commas - $line =~ s/^\s+//; - $line = "$prev_line $line\n"; + $LINE =~ s/^\s+//; + $LINE = "$prev_line $LINE\n"; } # see https://regex101.com/r/5iNptO/4 - $line =~ s/(?, +)?(const )?(\w+)(\<(?>[^<>]|(?4))*\>)?\s+[\w&*]+\s+SIP_PYARGREMOVE( = [^()]*(\(\s*(?:[^()]++|(?6))*\s*\))?)?(?()|,?)//g; + $LINE =~ s/(?, +)?(const )?(\w+)(\<(?>[^<>]|(?4))*\>)?\s+[\w&*]+\s+SIP_PYARGREMOVE( = [^()]*(\(\s*(?:[^()]++|(?6))*\s*\))?)?(?()|,?)//g; } - $line =~ s/SIP_FORCE//; + $LINE =~ s/SIP_FORCE//; } # detect a comment block, return 1 if found @@ -202,145 +219,144 @@ sub fix_annotations(){ sub detect_comment_block{ my %args = ( strict_mode => STRICT, @_ ); # dbg_info("detect comment strict:" . $args{strict_mode} ); - if ( $line =~ m/^\s*\/\*/ || $args{strict_mode} == UNSTRICT && $line =~ m/\/\*/ ){ + if ( $LINE =~ m/^\s*\/\*/ || $args{strict_mode} == UNSTRICT && $LINE =~ m/\/\*/ ){ dbg_info("found comment block"); do {no warnings 'uninitialized'; - $comment = processDoxygenLine( $line =~ s/^\s*\/\*(\*)?(.*?)\n?$/$2/r ); + $COMMENT = processDoxygenLine( $LINE =~ s/^\s*\/\*(\*)?(.*?)\n?$/$2/r ); }; - $comment =~ s/^\s*$//; - #$comment =~ s/^(\s*\n)*(.+)/$2/; - while ($line !~ m/\*\/\s*(\/\/.*?)?$/){ - $line = $lines[$line_idx]; - $line_idx++; - $comment .= processDoxygenLine( $line =~ s/\s*\*?(.*?)(\/)?\n?$/$1/r ); + $COMMENT =~ s/^\s*$//; + while ($LINE !~ m/\*\/\s*(\/\/.*?)?$/){ + $LINE = read_line(); + $COMMENT .= processDoxygenLine( $LINE =~ s/\s*\*?(.*?)(\/)?\n?$/$1/r ); } - $comment =~ s/\n+$//; - #push @output, dbg("XXX").$comment; + $COMMENT =~ s/\n+$//; return 1; } return 0; } + +write_header_footer(); + +# write some code in front of line to know where the output comes from +$debug == 0 or push @OUTPUT, "CODE SIP_RUN MultiLine\n"; + # main loop -while ($line_idx < $line_count){ - $line = $lines[$line_idx]; - $line_idx++; - my $actual_class = ''; - $actual_class = $CLASSNAME[$#CLASSNAME] unless $#CLASSNAME < 0; - $debug == 0 or print sprintf('L:%d DEP:%d ACC:%d BRC:%d SIP:%d MLT:%d CLSS: %d/', $line_idx, $#ACCESS, $ACCESS[$#ACCESS], $global_bracket_nesting_index[$#global_bracket_nesting_index], $SIP_RUN, $MULTILINE_DEFINITION, $#CLASSNAME).$actual_class." :: ".$line."\n"; +while ($LINE_IDX < $LINE_COUNT){ - if ($line =~ m/^\s*SIP_FEATURE\( (\w+) \)(.*)$/){ - push @output, dbg("SF1")."%Feature $1$2\n"; + $ACTUAL_CLASS = $CLASSNAME[$#CLASSNAME] unless $#CLASSNAME < 0; + $LINE = read_line(); + + + if ($LINE =~ m/^\s*SIP_FEATURE\( (\w+) \)(.*)$/){ + write_output("SF1", "%Feature $1$2\n"); next; } - if ($line =~ m/^\s*SIP_IF_FEATURE\( (\!?\w+) \)(.*)$/){ - push @output, dbg("SF2")."%If ($1)$2\n"; + if ($LINE =~ m/^\s*SIP_IF_FEATURE\( (\!?\w+) \)(.*)$/){ + write_output("SF2", "%If ($1)$2\n"); next; } - if ($line =~ m/^\s*SIP_CONVERT_TO_SUBCLASS_CODE(.*)$/){ - push @output, dbg("SCS")."%ConvertToSubClassCode$1\n"; + if ($LINE =~ m/^\s*SIP_CONVERT_TO_SUBCLASS_CODE(.*)$/){ + write_output("SCS", "%ConvertToSubClassCode$1\n"); next; } - if ($line =~ m/^\s*SIP_END(.*)$/){ - push @output, dbg("SEN")."%End$1\n"; + if ($LINE =~ m/^\s*SIP_END(.*)$/){ + write_output("SEN", "%End$1\n"); next; } # Skip preprocessor stuff - if ($line =~ m/^\s*#/){ + if ($LINE =~ m/^\s*#/){ # skip #if 0 blocks - if ( $line =~ m/^\s*#if (0|defined\(Q_OS_WIN\))/){ + if ( $LINE =~ m/^\s*#if (0|defined\(Q_OS_WIN\))/){ dbg_info("skipping #if $1 block"); my $nesting_index = 0; - while ($line_idx < $line_count){ - $line = $lines[$line_idx]; - $line_idx++; - if ( $line =~ m/^\s*#if(def)?\s+/ ){ + while ($LINE_IDX < $LINE_COUNT){ + $LINE = read_line(); + if ( $LINE =~ m/^\s*#if(def)?\s+/ ){ $nesting_index++; } - elsif ( $nesting_index == 0 && $line =~ m/^\s*#(endif|else)/ ){ - $comment = ''; + elsif ( $nesting_index == 0 && $LINE =~ m/^\s*#(endif|else)/ ){ + $COMMENT = ''; last; } - elsif ( $nesting_index != 0 && $line =~ m/^\s*#(endif)/ ){ + elsif ( $nesting_index != 0 && $LINE =~ m/^\s*#(endif)/ ){ $nesting_index--; } } next; } - if ( $line =~ m/^\s*#ifdef SIP_RUN/){ + if ( $LINE =~ m/^\s*#ifdef SIP_RUN/){ $SIP_RUN = 1; if ($ACCESS[$#ACCESS] == PRIVATE){ dbg_info("writing private content"); - push @output, dbg("PRV1").$private_section_line."\n"; + write_output("PRV1", $PRIVATE_SECTION_LINE."\n"); } next; } if ( $SIP_RUN == 1 ){ - if ( $line =~ m/^\s*#endif/ ){ - if ( $global_ifdef_nesting_index == 0 ){ + if ( $LINE =~ m/^\s*#endif/ ){ + if ( $GLOB_IFDEF_NESTING_IDX == 0 ){ $SIP_RUN = 0; next; } else { - $global_ifdef_nesting_index--; + $GLOB_IFDEF_NESTING_IDX--; } } - if ( $line =~ m/^\s*#if(def)?\s+/ ){ - $global_ifdef_nesting_index++; + if ( $LINE =~ m/^\s*#if(def)?\s+/ ){ + $GLOB_IFDEF_NESTING_IDX++; } # if there is an else at this level, code will be ignored i.e. not SIP_RUN - if ( $line =~ m/^\s*#else/ && $global_ifdef_nesting_index == 0){ - while ($line_idx < $line_count){ - $line = $lines[$line_idx]; - $line_idx++; - if ( $line =~ m/^\s*#if(def)?\s+/ ){ - $global_ifdef_nesting_index++; + if ( $LINE =~ m/^\s*#else/ && $GLOB_IFDEF_NESTING_IDX == 0){ + while ($LINE_IDX < $LINE_COUNT){ + $LINE = read_line(); + if ( $LINE =~ m/^\s*#if(def)?\s+/ ){ + $GLOB_IFDEF_NESTING_IDX++; } - elsif ( $line =~ m/^\s*#endif/ ){ - if ( $global_ifdef_nesting_index == 0 ){ - $comment = ''; + elsif ( $LINE =~ m/^\s*#endif/ ){ + if ( $GLOB_IFDEF_NESTING_IDX == 0 ){ + $COMMENT = ''; $SIP_RUN = 0; last; } else { - $global_ifdef_nesting_index--; + $GLOB_IFDEF_NESTING_IDX--; } } } next; } } - elsif ( $line =~ m/^\s*#ifndef SIP_RUN/){ + elsif ( $LINE =~ m/^\s*#ifndef SIP_RUN/){ # code is ignored here - while ($line_idx < $line_count){ - $line = $lines[$line_idx]; - $line_idx++; - if ( $line =~ m/^\s*#if(def)?\s+/ ){ - $global_ifdef_nesting_index++; + while ($LINE_IDX < $LINE_COUNT){ + $LINE = read_line(); + if ( $LINE =~ m/^\s*#if(def)?\s+/ ){ + $GLOB_IFDEF_NESTING_IDX++; } - elsif ( $line =~ m/^\s*#else/ && $global_ifdef_nesting_index == 0 ){ + elsif ( $LINE =~ m/^\s*#else/ && $GLOB_IFDEF_NESTING_IDX == 0 ){ # code here will be printed out if ($ACCESS[$#ACCESS] == PRIVATE){ dbg_info("writing private content"); - push @output, dbg("PRV2").$private_section_line."\n"; + write_output("PRV2", $PRIVATE_SECTION_LINE."\n"); } $SIP_RUN = 1; last; } - elsif ( $line =~ m/^\s*#endif/ ){ - if ( $global_ifdef_nesting_index == 0 ){ - $comment = ''; + elsif ( $LINE =~ m/^\s*#endif/ ){ + if ( $GLOB_IFDEF_NESTING_IDX == 0 ){ + $COMMENT = ''; $SIP_RUN = 0; last; } else { - $global_ifdef_nesting_index--; + $GLOB_IFDEF_NESTING_IDX--; } } } @@ -354,14 +370,14 @@ while ($line_idx < $line_count){ # TYPE HEADER CODE if ( $HEADER_CODE && $SIP_RUN == 0 ){ $HEADER_CODE = 0; - push @output, dbg("HCE")."%End\n"; + write_output("HCE", "%End\n"); } # Skip forward declarations - if ($line =~ m/^\s*(class|struct) \w+(? *SIP_EXTERNAL)?;\s*(\/\/.*)?$/){ + if ($LINE =~ m/^\s*(class|struct) \w+(? *SIP_EXTERNAL)?;\s*(\/\/.*)?$/){ if ($+{external}){ dbg_info('do not skip external forward declaration'); - $comment = ''; + $COMMENT = ''; } else { @@ -370,21 +386,21 @@ while ($line_idx < $line_count){ } } # Skip Q_OBJECT, Q_PROPERTY, Q_ENUM, Q_GADGET - if ($line =~ m/^\s*Q_(OBJECT|ENUMS|PROPERTY|GADGET|DECLARE_METATYPE|DECLARE_TYPEINFO|DECL_DEPRECATED).*?$/){ + if ($LINE =~ m/^\s*Q_(OBJECT|ENUMS|PROPERTY|GADGET|DECLARE_METATYPE|DECLARE_TYPEINFO|DECL_DEPRECATED).*?$/){ next; } # SIP_SKIP - if ( $line =~ m/SIP_SKIP/ ){ + if ( $LINE =~ m/SIP_SKIP/ ){ dbg_info('SIP SKIP!'); - $comment = ''; + $COMMENT = ''; # if multiline definition, remove previous lines if ( $MULTILINE_DEFINITION == 1){ dbg_info('SIP_SKIP with MultiLine'); my $opening_line = ''; while ( $opening_line !~ m/^[^()]*\(([^()]*\([^()]*\)[^()]*)*[^()]*$/){ - $opening_line = pop(@output); - $#output >= 0 or die 'could not reach opening definition'; + $opening_line = pop(@OUTPUT); + $#OUTPUT >= 0 or die 'could not reach opening definition'; } dbg_info("removed multiline definition of SIP_SKIP method"); $MULTILINE_DEFINITION = 0; @@ -400,33 +416,33 @@ while ($line_idx < $line_count){ next; } - if ( $line =~ m/^\s*struct(\s+\w+_EXPORT)?\s+\w+$/ ) { + if ( $LINE =~ m/^\s*struct(\s+\w+_EXPORT)?\s+\w+$/ ) { dbg_info(" going to struct => public"); push @CLASSNAME, $CLASSNAME[$#CLASSNAME]; # fake new class since struct has considered similarly push @ACCESS, PUBLIC; push @EXPORTED, $EXPORTED[-1]; - push @global_bracket_nesting_index, 0; + push @GLOB_BRACKET_NESTING_IDX, 0; } # class declaration started # https://regex101.com/r/6FWntP/6 - if ( $line =~ m/^(\s*class)\s+([A-Z]+_EXPORT\s+)?(\w+)(\s*\:\s*(public|private)\s+\w+(<([\w]|::)+>)?(::\w+(<\w+>)?)*(,\s*(public|private)\s+\w+(<([\w]|::)+>)?(::\w+(<\w+>)?)*)*)?(?\s*SIP_\w+)?(?!;)$/ ){ + if ( $LINE =~ m/^(\s*class)\s+([A-Z]+_EXPORT\s+)?(\w+)(\s*\:\s*(public|private)\s+\w+(<([\w]|::)+>)?(::\w+(<\w+>)?)*(,\s*(public|private)\s+\w+(<([\w]|::)+>)?(::\w+(<\w+>)?)*)*)?(?\s*SIP_\w+)?(?!;)$/ ){ dbg_info("class definition started"); push @ACCESS, PUBLIC; push @EXPORTED, 0; - push @global_bracket_nesting_index, 0; + push @GLOB_BRACKET_NESTING_IDX, 0; my @template_inheritance_template = (); my @template_inheritance_class = (); do {no warnings 'uninitialized'; push @CLASSNAME, $3; dbg_info("class: ".$CLASSNAME[$#CLASSNAME]); - if ($line =~ m/\b[A-Z]+_EXPORT\b/ || $#CLASSNAME != 0 || $lines[$line_idx-2] =~ m/^\s*template//g; # remove remaining templates $m =~ s/([:,])\s*,/$1/g; $m =~ s/(\s*[:,])?\s*$//; - $line .= $m; + $LINE .= $m; } if (defined $+{annot}) { - $line .= "$+{annot}"; + $LINE .= "$+{annot}"; fix_annotations(); } - $line .= "\n{\n"; - if ( $comment !~ m/^\s*$/ ){ - $line .= "%Docstring\n$comment\n%End\n"; + $LINE .= "\n{\n"; + if ( $COMMENT !~ m/^\s*$/ ){ + $LINE .= "%Docstring\n$COMMENT\n%End\n"; } - $line .= "\n%TypeHeaderCode\n#include \"" . basename($headerfile) . "\""; + $LINE .= "\n%TypeHeaderCode\n#include \"" . basename($headerfile) . "\""; # for template based inheritance, add a typedef to define the base type # add it to the class and to the TypeHeaderCode # also include the template header @@ -466,9 +482,9 @@ while ($line_idx < $line_count){ if (exists $SIP_CONFIG->{class_headerfile}->{$tpl}){ $tpl_header = $SIP_CONFIG->{class_headerfile}->{$tpl}; } - $line = "\ntypedef $tpl<$cls> ${tpl}${cls}Base;\n\n$line"; - $line .= "\n#include \"" . $tpl_header . "\""; - $line .= "\ntypedef $tpl<$cls> ${tpl}${cls}Base;"; + $LINE = "\ntypedef $tpl<$cls> ${tpl}${cls}Base;\n\n$LINE"; + $LINE .= "\n#include \"" . $tpl_header . "\""; + $LINE .= "\ntypedef $tpl<$cls> ${tpl}${cls}Base;"; } if ( PRIVATE ~~ @ACCESS && $#ACCESS != 0){ # do not write anything in PRIVATE context and not top level @@ -477,15 +493,14 @@ while ($line_idx < $line_count){ } $ACCESS[$#ACCESS] = PRIVATE; # private by default - push @output, dbg("CLS")."$line\n"; + write_output("CLS", "$LINE\n"); # Skip opening curly bracket, incrementing hereunder - my $skip = $lines[$line_idx]; - $line_idx++; + my $skip = read_line(); $skip =~ m/^\s*{\s*$/ || die "Unexpected content on line $skip"; - $global_bracket_nesting_index[$#global_bracket_nesting_index]++; + $GLOB_BRACKET_NESTING_IDX[$#GLOB_BRACKET_NESTING_IDX]++; - $comment = ''; + $COMMENT = ''; $HEADER_CODE = 1; $ACCESS[$#ACCESS] = PRIVATE; next; @@ -494,16 +509,16 @@ while ($line_idx < $line_count){ # bracket balance in class/struct tree if ($SIP_RUN == 0){ my $bracket_balance = 0; - $bracket_balance += $line =~ tr/\{//; - $bracket_balance -= $line =~ tr/\}//; + $bracket_balance += $LINE =~ tr/\{//; + $bracket_balance -= $LINE =~ tr/\}//; if ($bracket_balance != 0){ - $global_bracket_nesting_index[$#global_bracket_nesting_index] += $bracket_balance; - if ($global_bracket_nesting_index[$#global_bracket_nesting_index] == 0){ + $GLOB_BRACKET_NESTING_IDX[$#GLOB_BRACKET_NESTING_IDX] += $bracket_balance; + if ($GLOB_BRACKET_NESTING_IDX[$#GLOB_BRACKET_NESTING_IDX] == 0){ dbg_info(" going up in class/struct tree"); if ($#ACCESS > 0){ - pop(@global_bracket_nesting_index); + pop(@GLOB_BRACKET_NESTING_IDX); pop(@ACCESS); - die "Class $CLASSNAME[$#CLASSNAME] in $headerfile at line $line_idx should be exported with appropriate [LIB]_EXPORT macro. If this should not be available in python, wrap it in a `#ifndef SIP_RUN` block." + die "Class $CLASSNAME[$#CLASSNAME] in $headerfile at line $LINE_IDX should be exported with appropriate [LIB]_EXPORT macro. If this should not be available in python, wrap it in a `#ifndef SIP_RUN` block." if $EXPORTED[-1] == 0; pop @EXPORTED; } @@ -514,42 +529,42 @@ while ($line_idx < $line_count){ dbg_info $ACCESS[$#ACCESS] = PUBLIC; } - $comment = ''; - $return_type = ''; - $private_section_line = ''; + $COMMENT = ''; + $RETURN_TYPE = ''; + $PRIVATE_SECTION_LINE = ''; } - dbg_info("new bracket balance: @global_bracket_nesting_index"); + dbg_info("new bracket balance: @GLOB_BRACKET_NESTING_IDX"); } } # Private members (exclude SIP_RUN) - if ( $line =~ m/^\s*private( slots)?:/ ){ + if ( $LINE =~ m/^\s*private( slots)?:/ ){ $ACCESS[$#ACCESS] = PRIVATE; - $private_section_line = $line; - $comment = ''; + $PRIVATE_SECTION_LINE = $LINE; + $COMMENT = ''; dbg_info("going private"); next; } - elsif ( $line =~ m/^\s*(public( slots)?|signals):.*$/ ){ + elsif ( $LINE =~ m/^\s*(public( slots)?|signals):.*$/ ){ dbg_info("going public"); $ACCESS[$#ACCESS] = PUBLIC; - $comment = ''; + $COMMENT = ''; } - elsif ( $line =~ m/^\s*(protected)( slots)?:.*$/ ){ + elsif ( $LINE =~ m/^\s*(protected)( slots)?:.*$/ ){ dbg_info("going protected"); $ACCESS[$#ACCESS] = PROTECTED; - $comment = ''; + $COMMENT = ''; } - elsif ( $ACCESS[$#ACCESS] == PRIVATE && $line =~ m/SIP_FORCE/){ + elsif ( $ACCESS[$#ACCESS] == PRIVATE && $LINE =~ m/SIP_FORCE/){ dbg_info("private with SIP_FORCE"); - push @output, dbg("PRV3").$private_section_line."\n"; + write_output("PRV3", $PRIVATE_SECTION_LINE."\n"); } elsif ( PRIVATE ~~ @ACCESS && $SIP_RUN == 0 ) { - $comment = ''; + $COMMENT = ''; next; } # Skip operators - if ( $line =~ m/operator(=|<<|>>|->)\s*\(/ ){ + if ( $LINE =~ m/operator(=|<<|>>|->)\s*\(/ ){ dbg_info("skip operator"); detect_and_remove_following_body_or_initializerlist(); next; @@ -557,48 +572,46 @@ while ($line_idx < $line_count){ # save comments and do not print them, except in SIP_RUN if ( $SIP_RUN == 0 ){ - if ( $line =~ m/^\s*\/\// ){ - if ($line =~ m/^\s*\/\/\!\s*(.*?)\n?$/){ - $comment = processDoxygenLine( $1 ); - $comment =~ s/\n+$//; + if ( $LINE =~ m/^\s*\/\// ){ + if ($LINE =~ m/^\s*\/\/\!\s*(.*?)\n?$/){ + $COMMENT = processDoxygenLine( $1 ); + $COMMENT =~ s/\n+$//; } - elsif ($lines[$line_idx-1] !~ m/\*\/.*/) { - $comment = ''; + elsif ($INPUT_LINES[$LINE_IDX-1] !~ m/\*\/.*/) { + $COMMENT = ''; } next; } } # Enum declaration - if ( $line =~ m/^\s*enum\s+\w+.*?$/ ){ - push @output, dbg("ENU1")."$line\n"; - if ($line =~ m/\{((\s*\w+)(\s*=\s*[\w\s\d<|]+.*?)?(,?))+\s*\}/){ + if ( $LINE =~ m/^\s*enum\s+\w+.*?$/ ){ + write_output("ENU1", "$LINE\n"); + if ($LINE =~ m/\{((\s*\w+)(\s*=\s*[\w\s\d<|]+.*?)?(,?))+\s*\}/){ # one line declaration - $line !~ m/=/ or die 'spify.pl does not handle enum one liners with value assignment. Use multiple lines instead.'; + $LINE !~ m/=/ or die 'spify.pl does not handle enum one liners with value assignment. Use multiple lines instead.'; next; } else { - $line = $lines[$line_idx]; - $line_idx++; - $line =~ m/^\s*\{\s*$/ || die "Unexpected content: enum should be followed by {\nline: $line"; - push @output, dbg("ENU2")."$line\n"; - while ($line_idx < $line_count){ - $line = $lines[$line_idx]; - $line_idx++; + $LINE = read_line(); + $LINE =~ m/^\s*\{\s*$/ || die "Unexpected content: enum should be followed by {\nline: $LINE"; + write_output("ENU2", "$LINE\n"); + while ($LINE_IDX < $LINE_COUNT){ + $LINE = read_line(); if (detect_comment_block()){ next; } - if ($line =~ m/\};/){ + if ($LINE =~ m/\};/){ last; } - my $enum_val = $line =~ s/(\s*\w+)(\s*=\s*[\w\s\d<|]+.*?)?(,?).*$/$1$3/r; - push @output, dbg("ENU3")."$enum_val\n"; + my $enum_val = $LINE =~ s/(\s*\w+)(\s*=\s*[\w\s\d<|]+.*?)?(,?).*$/$1$3/r; + write_output("ENU3", "$enum_val\n"); detect_comment_block(strict_mode => UNSTRICT); } - push @output, dbg("ENU4")."$line\n"; + write_output("ENU4", "$LINE\n"); # enums don't have Docstring apparently - $comment = ''; + $COMMENT = ''; next; } } @@ -607,147 +620,146 @@ while ($line_idx < $line_count){ # https://regex101.com/r/gUBZUk/9 if ( $SIP_RUN != 1 && $ACCESS[$#ACCESS] != PUBLIC && - $line =~ m/^\s*(?:template<\w+>\s+)?(?:(const|mutable|static|friend|unsigned)\s+)*\w+(::\w+)?(<([\w<> *&,()]|::)+>)?(,?\s+\*?\w+( = (-?\d+(\.\d+)?|\w+(\([^()]+\))?)|\[\d+\])?)+;/){ + $LINE =~ m/^\s*(?:template<\w+>\s+)?(?:(const|mutable|static|friend|unsigned)\s+)*\w+(::\w+)?(<([\w<> *&,()]|::)+>)?(,?\s+\*?\w+( = (-?\d+(\.\d+)?|\w+(\([^()]+\))?)|\[\d+\])?)+;/){ dbg_info("skip non-method member declaration in non-public sections"); next; } # remove static const value assignment # https://regex101.com/r/DyWkgn/4 - $line !~ m/^\s*const static \w+/ or die "const static should be written static const in $CLASSNAME[$#CLASSNAME] at line $line_idx"; - $line =~ s/^(\s*static const \w+(?:<(?:[\w()<>, ]|::)+>)? \w+) = .*([|;])\s*(\/\/.*)?$/$1;/; + $LINE !~ m/^\s*const static \w+/ or die "const static should be written static const in $CLASSNAME[$#CLASSNAME] at line $LINE_IDX"; + $LINE =~ s/^(\s*static const \w+(?:<(?:[\w()<>, ]|::)+>)? \w+) = .*([|;])\s*(\/\/.*)?$/$1;/; if ( defined $2 && $2 =~ m/\|/ ){ dbg_info("multiline const static assignment"); my $skip = ''; while ( $skip !~ m/;\s*(\/\/.*?)?$/ ){ - $skip = $lines[$line_idx]; - $line_idx++; + $skip = read_line(); } } # remove struct member assignment - if ( $SIP_RUN != 1 && $ACCESS[$#ACCESS] == PUBLIC && $line =~ m/^(\s*\w+[\w<> *&:,]* \*?\w+) = \w+(\([^()]+\))?;/ ){ + if ( $SIP_RUN != 1 && $ACCESS[$#ACCESS] == PUBLIC && $LINE =~ m/^(\s*\w+[\w<> *&:,]* \*?\w+) = \w+(\([^()]+\))?;/ ){ dbg_info("remove struct member assignment"); - $line = "$1;"; + $LINE = "$1;"; } # catch Q_DECLARE_FLAGS - if ( $line =~ m/^(\s*)Q_DECLARE_FLAGS\(\s*(.*?)\s*,\s*(.*?)\s*\)\s*$/ ){ - my $actual_class = $CLASSNAME[$#CLASSNAME]; - dbg_info("Declare flags: $actual_class"); - $line = "$1typedef QFlags<$actual_class::$3> $2;\n"; - $qflag_hash{"$actual_class::$2"} = "$actual_class::$3"; + if ( $LINE =~ m/^(\s*)Q_DECLARE_FLAGS\(\s*(.*?)\s*,\s*(.*?)\s*\)\s*$/ ){ + my $ACTUAL_CLASS = $CLASSNAME[$#CLASSNAME]; + dbg_info("Declare flags: $ACTUAL_CLASS"); + $LINE = "$1typedef QFlags<$ACTUAL_CLASS::$3> $2;\n"; + $QFLAG_HASH{"$ACTUAL_CLASS::$2"} = "$ACTUAL_CLASS::$3"; } # catch Q_DECLARE_OPERATORS_FOR_FLAGS - if ( $line =~ m/^(\s*)Q_DECLARE_OPERATORS_FOR_FLAGS\(\s*(.*?)\s*\)\s*$/ ){ - my $flag = $qflag_hash{$2}; - $line = "$1QFlags<$flag> operator|($flag f1, QFlags<$flag> f2);\n"; + if ( $LINE =~ m/^(\s*)Q_DECLARE_OPERATORS_FOR_FLAGS\(\s*(.*?)\s*\)\s*$/ ){ + my $flag = $QFLAG_HASH{$2}; + $LINE = "$1QFlags<$flag> operator|($flag f1, QFlags<$flag> f2);\n"; } # remove Q_INVOKABLE - $line =~ s/^(\s*)Q_INVOKABLE /$1/; + $LINE =~ s/^(\s*)Q_INVOKABLE /$1/; do {no warnings 'uninitialized'; # remove keywords - if ( $line =~ m/\boverride\b/){ - $is_override = 1; + if ( $LINE =~ m/\boverride\b/){ + $IS_OVERRIDE = 1; # handle multiline definition to add virtual keyword on opening line if ( $MULTILINE_DEFINITION == 1 ){ - my $virtual_line = $line; - my $virtual_line_idx = $line_idx; + my $virtual_line = $LINE; + my $virtual_line_idx = $LINE_IDX; dbg_info("handle multiline definition to add virtual keyword on opening line"); while ( $virtual_line !~ m/^[^()]*\(([^()]*\([^()]*\)[^()]*)*[^()]*$/){ $virtual_line_idx--; - $virtual_line = $lines[$virtual_line_idx]; + $virtual_line = $INPUT_LINES[$virtual_line_idx]; $virtual_line_idx >= 0 or die 'could not reach opening definition'; } if ( $virtual_line !~ m/^(\s*)virtual\b(.*)$/ ){ - my $idx = $#output-$line_idx+$virtual_line_idx+2; - #print "len: $#output line_idx: $line_idx virt: $virtual_line_idx\n"idx: $idx\n$output[$idx]\n"; - $output[$idx] = $virtual_line =~ s/^(\s*?)\b(.*)$/$1 virtual $2\n/r; + my $idx = $#OUTPUT-$LINE_IDX+$virtual_line_idx+2; + #print "len: $#OUTPUT line_idx: $LINE_IDX virt: $virtual_line_idx\n"idx: $idx\n$OUTPUT[$idx]\n"; + $OUTPUT[$idx] = $virtual_line =~ s/^(\s*?)\b(.*)$/$1 virtual $2\n/r; } } - elsif ( $line !~ m/^(\s*)virtual\b(.*)$/ ){ + elsif ( $LINE !~ m/^(\s*)virtual\b(.*)$/ ){ #sip often requires the virtual keyword to be present, or it chokes on covariant return types #in overridden methods - $line =~ s/^(\s*?)\b(.*)$/$1virtual $2\n/; + $LINE =~ s/^(\s*?)\b(.*)$/$1virtual $2\n/; } } # keyword fixes - $line =~ s/^(\s*template<)(?:class|typename) (\w+>)(.*)$/$1$2$3/; - $line =~ s/\s*\boverride\b//; - $line =~ s/^(\s*)?(const )?(virtual |static )?inline /$1$2$3/; - $line =~ s/\bnullptr\b/0/g; - $line =~ s/\s*=\s*default\b//g; + $LINE =~ s/^(\s*template<)(?:class|typename) (\w+>)(.*)$/$1$2$3/; + $LINE =~ s/\s*\boverride\b//; + $LINE =~ s/^(\s*)?(const )?(virtual |static )?inline /$1$2$3/; + $LINE =~ s/\bnullptr\b/0/g; + $LINE =~ s/\s*=\s*default\b//g; - if( $line =~ /\w+_EXPORT/ ) { + if( $LINE =~ /\w+_EXPORT/ ) { $EXPORTED[-1]++; - $line =~ s/\b\w+_EXPORT\s+//g; + $LINE =~ s/\b\w+_EXPORT\s+//g; } # remove constructor definition, function bodies, member initializing list $SIP_RUN == 1 or detect_and_remove_following_body_or_initializerlist(); # remove inline declarations - if ( $line =~ m/^(\s*)?(static |const )*(([\w:]+(<.*?>)?\s+(\*|&)?)?(\w+)( (?:const*?))*)\s*(\{.*\});(\s*\/\/.*)?$/ ){ + if ( $LINE =~ m/^(\s*)?(static |const )*(([\w:]+(<.*?>)?\s+(\*|&)?)?(\w+)( (?:const*?))*)\s*(\{.*\});(\s*\/\/.*)?$/ ){ my $newline = "$1$3;"; - $line = $newline; + $LINE = $newline; } - if ( $line =~ m/^\s*(?:const |virtual |static |inline )*(?!explicit)([\w:]+(?:<.*?>)?)\s+(?:\*|&)?(?:\w+|operator.{1,2})\(.*$/ ){ + if ( $LINE =~ m/^\s*(?:const |virtual |static |inline )*(?!explicit)([\w:]+(?:<.*?>)?)\s+(?:\*|&)?(?:\w+|operator.{1,2})\(.*$/ ){ if ($1 !~ m/(void|SIP_PYOBJECT|operator|return|QFlag)/ ){ - $return_type = $1; + $RETURN_TYPE = $1; # replace :: with . (changes c++ style namespace/class directives to Python style) - $return_type =~ s/::/./g; + $RETURN_TYPE =~ s/::/./g; # replace with builtin Python types - $return_type =~ s/\bdouble\b/float/; - $return_type =~ s/\bQString\b/str/; - $return_type =~ s/\bQStringList\b/list of str/; - if ( $return_type =~ m/^(?:QList|QVector)<\s*(.*?)[\s*\*]*>$/ ){ - $return_type = "list of $1"; + $RETURN_TYPE =~ s/\bdouble\b/float/; + $RETURN_TYPE =~ s/\bQString\b/str/; + $RETURN_TYPE =~ s/\bQStringList\b/list of str/; + if ( $RETURN_TYPE =~ m/^(?:QList|QVector)<\s*(.*?)[\s*\*]*>$/ ){ + $RETURN_TYPE = "list of $1"; } - if ( $return_type =~ m/^QSet<\s*(.*?)[\s*\*]*>$/ ){ - $return_type = "set of $1"; + if ( $RETURN_TYPE =~ m/^QSet<\s*(.*?)[\s*\*]*>$/ ){ + $RETURN_TYPE = "set of $1"; } } } }; # deleted functions - if ( $line =~ m/^(\s*)?(const )?(virtual |static )?((\w+(<.*?>)?\s+(\*|&)?)?(\w+|operator.{1,2})\(.*?(\(.*\))*.*\)( const)?)\s*= delete;(\s*\/\/.*)?$/ ){ - $comment = ''; + if ( $LINE =~ m/^(\s*)?(const )?(virtual |static )?((\w+(<.*?>)?\s+(\*|&)?)?(\w+|operator.{1,2})\(.*?(\(.*\))*.*\)( const)?)\s*= delete;(\s*\/\/.*)?$/ ){ + $COMMENT = ''; next; } # remove export macro from struct definition - $line =~ s/^(\s*struct )\w+_EXPORT (.+)$/$1$2/; + $LINE =~ s/^(\s*struct )\w+_EXPORT (.+)$/$1$2/; fix_annotations(); # fix astyle placing space after % character - $line =~ s/\s*% (MappedType|Type(Header)?Code|Module(Header)?Code|Convert(From|To)TypeCode|MethodCode|End)/%$1/; - $line =~ s/\/\s+GetWrapper\s+\//\/GetWrapper\//; + $LINE =~ s/\s*% (MappedType|Type(Header)?Code|Module(Header)?Code|Convert(From|To)TypeCode|MethodCode|End)/%$1/; + $LINE =~ s/\/\s+GetWrapper\s+\//\/GetWrapper\//; - push @output, dbg("NOR")."$line\n"; + write_output("NOR", "$LINE\n"); # multiline definition (parenthesis left open) if ( $MULTILINE_DEFINITION == 1 ){ dbg_info("on multiline"); # https://regex101.com/r/DN01iM/2 - if ( $line =~ m/^([^()]+(\((?:[^()]++|(?1))*\)))*[^()]*\)[^()]*$/){ + if ( $LINE =~ m/^([^()]+(\((?:[^()]++|(?1))*\)))*[^()]*\)[^()]*$/){ $MULTILINE_DEFINITION = 0; dbg_info("ending multiline"); # remove potential following body - if ( $SIP_RUN == 0 && $line !~ m/(\{.*\}|;)\s*(\/\/.*)?$/ ){ + if ( $SIP_RUN == 0 && $LINE !~ m/(\{.*\}|;)\s*(\/\/.*)?$/ ){ dbg_info("remove following body of multiline def"); - my $last_line = $line; + my $last_line = $LINE; remove_following_body_or_initializerlist(); # add missing semi column - my $dummy = pop(@output); - push @output, dbg("MLT")."$last_line;\n"; + my $dummy = pop(@OUTPUT); + write_output("MLT", "$last_line;\n"); } } else @@ -755,61 +767,54 @@ while ($line_idx < $line_count){ next; } } - elsif ( $line =~ m/^[^()]+\([^()]*([^()]*\([^()]*\)[^()]*)*[^)]*$/ ){ + elsif ( $LINE =~ m/^[^()]+\([^()]*([^()]*\([^()]*\)[^()]*)*[^)]*$/ ){ dbg_info("Mulitline detected"); $MULTILINE_DEFINITION = 1; next; } # write comment - if ( $line =~ m/^\s*$/ ) + if ( $LINE =~ m/^\s*$/ ) { - $is_override = 0; + $IS_OVERRIDE = 0; next; } - if ( $line =~ m/^\s*template<.*>/ ){ + if ( $LINE =~ m/^\s*template<.*>/ ){ # do not comment now for templates, wait for class definition next; } - elsif ( $line =~ m/\/\// || - $line =~ m/\s*typedef / || - $line =~ m/\s*struct / || - $line =~ m/operator\[\]\(/ || - $line =~ m/operator==/ || - ($line =~ m/operator[!+-=*\/\[\]]{1,2}/ && $#ACCESS == 0) || # apparently global operators cannot be documented - $line =~ m/^\s*%\w+(.*)?$/ ){ + elsif ( $LINE =~ m/\/\// || + $LINE =~ m/\s*typedef / || + $LINE =~ m/\s*struct / || + $LINE =~ m/operator\[\]\(/ || + $LINE =~ m/operator==/ || + ($LINE =~ m/operator[!+-=*\/\[\]]{1,2}/ && $#ACCESS == 0) || # apparently global operators cannot be documented + $LINE =~ m/^\s*%\w+(.*)?$/ ){ dbg_info('skipping comment'); - $comment = ''; - $return_type = ''; + $COMMENT = ''; + $RETURN_TYPE = ''; } - elsif ( $comment !~ m/^\s*$/ || $return_type ne ''){ - if ( $is_override == 1 && $comment =~ m/^\s*$/ ){ + elsif ( $COMMENT !~ m/^\s*$/ || $RETURN_TYPE ne ''){ + if ( $IS_OVERRIDE == 1 && $COMMENT =~ m/^\s*$/ ){ # overridden method with no new docs - so don't create a Docstring and use # parent class Docstring } else { dbg_info('writing comment'); - push @output, dbg("CM1")."%Docstring\n"; - if ( $comment !~ m/^\s*$/ ){ - push @output, dbg("CM2")."$comment\n"; + write_output("CM1", "%Docstring\n"); + if ( $COMMENT !~ m/^\s*$/ ){ + write_output("CM2", "$COMMENT\n"); } - if ($return_type ne '' ){ - push @output, dbg("CM3")." :rtype: $return_type\n"; + if ($RETURN_TYPE ne '' ){ + write_output("CM3", " :rtype: $RETURN_TYPE\n"); } - push @output, dbg("CM4")."%End\n"; + write_output("CM4", "%End\n"); } - $comment = ''; - $return_type = ''; - $is_override = 0; + $COMMENT = ''; + $RETURN_TYPE = ''; + $IS_OVERRIDE = 0; } } -push @output, "/************************************************************************\n"; -push @output, " * This file has been generated automatically from *\n"; -push @output, " * *\n"; -push @output, sprintf " * %-*s *\n", 68, $headerfile; -push @output, " * *\n"; -push @output, " * Do not edit manually ! Edit header and run scripts/sipify.pl again *\n"; -push @output, " ************************************************************************/\n"; +write_header_footer(); - -print join('',@output); +print join('',@OUTPUT);