📄 prepare-changelog
字号:
my $match = $1; if ($match eq "/*") { if (!s-/\*.*?\*/--) { s-/\*.*--; $in_comment = 1; } } elsif ($match eq "//") { s-//.*--; } else { # ' or " if (!s-$match([^\\]|\\.)*?$match--) { warn "mismatched quotes at line $. in $file_name\n"; s-$match.*--; } } } # continued method declaration if ($in_method_declaration) { my $original = $_; my $method_cont = $_; chomp $method_cont; $method_cont =~ s/[;\{].*//; $potential_method_spec = "${potential_method_spec} ${method_cont}"; $_ = $original; if (/;/) { $potential_start = 0; $potential_method_spec = ""; $potential_method_char = ""; $in_method_declaration = 0; s/^[^;\{]*//; } elsif (/{/) { my $selector = method_decl_to_selector ($potential_method_spec); $potential_name = "${potential_method_char}\[${interface_name} ${selector}\]"; $potential_method_spec = ""; $potential_method_char = ""; $in_method_declaration = 0; $_ = $original; s/^[^;{]*//; } elsif (/\@end/) { $in_method_declaration = 0; $interface_name = ""; $_ = $original; } else { next; } } # start of method declaration if ((my $method_char, my $method_spec) = m&^([-+])([^0-9;][^;]*);?$&) { my $original = $_; if ($interface_name) { chomp $method_spec; $method_spec =~ s/\{.*//; $potential_method_char = $method_char; $potential_method_spec = $method_spec; $potential_start = $.; $in_method_declaration = 1; } else { warn "declaring a method but don't have interface on line $. in $file_name\n"; } $_ = $original; if (/\{/) { my $selector = method_decl_to_selector ($potential_method_spec); $potential_name = "${potential_method_char}\[${interface_name} ${selector}\]"; $potential_method_spec = ""; $potential_method_char = ""; $in_method_declaration = 0; $_ = $original; s/^[^{]*//; } elsif (/\@end/) { $in_method_declaration = 0; $interface_name = ""; $_ = $original; } else { next; } } # Find function, interface and method names. while (m&((?:[[:word:]]+::)*operator(?:[ \t]*\(\)|[^()]*)|[[:word:]:~]+|[(){}:;])|\@(?:implementation|interface|protocol)\s+(\w+)[^{]*&g) { # interface name if ($2) { $interface_name = $2; next; } # Open parenthesis. if ($1 eq "(") { $potential_name = $word unless $in_parentheses || $skip_til_brace_or_semicolon; $in_parentheses++; next; } # Close parenthesis. if ($1 eq ")") { $in_parentheses--; next; } # C++ constructor initializers if ($1 eq ":") { $skip_til_brace_or_semicolon = 1 unless ($in_parentheses || $in_braces); } # Open brace. if ($1 eq "{") { $skip_til_brace_or_semicolon = 0; if ($potential_namespace) { push @namespaces, $potential_namespace; $potential_namespace = ""; next; } # Promote potential name to real function name at the # start of the outer level set of braces (function body?). if (!$in_braces and $potential_start) { $start = $potential_start; $name = $potential_name; if (@namespaces && (length($name) < 2 || substr($name,1,1) ne "[")) { $name = join ('::', @namespaces, $name); } } $in_method_declaration = 0; $brace_start = $. if (!$in_braces); $in_braces++; next; } # Close brace. if ($1 eq "}") { if (!$in_braces && @namespaces) { pop @namespaces; next; } $in_braces--; $brace_end = $. if (!$in_braces); # End of an outer level set of braces. # This could be a function body. if (!$in_braces and $name) { push @ranges, [ $start, $., $name ]; $name = ""; } $potential_start = 0; $potential_name = ""; next; } # Semicolon. if ($1 eq ";") { $skip_til_brace_or_semicolon = 0; $potential_start = 0; $potential_name = ""; $in_method_declaration = 0; next; } # Ignore "const" method qualifier. if ($1 eq "const") { next; } if ($1 eq "namespace" || $1 eq "class" || $1 eq "struct") { $next_word_could_be_namespace = 1; next; } # Word. $word = $1; if (!$skip_til_brace_or_semicolon) { if ($next_word_could_be_namespace) { $potential_namespace = $word; $next_word_could_be_namespace = 0; } elsif ($potential_namespace) { $potential_namespace = ""; } if (!$in_parentheses) { $potential_start = 0; $potential_name = ""; } if (!$potential_start) { $potential_start = $.; $potential_name = ""; } } } } warn "missing close braces in $file_name (probable start at $brace_start)\n" if ($in_braces > 0); warn "too many close braces in $file_name (probable start at $brace_end)\n" if ($in_braces < 0); warn "mismatched parentheses in $file_name\n" if $in_parentheses; return @ranges;}# Read a file and get all the line ranges of the things that look like Java# classes, interfaces and methods.## A class or interface name is the word that immediately follows# `class' or `interface' when followed by an open curly brace and not# a semicolon. It can appear at the top level, or inside another class# or interface block, but not inside a function block## A class or interface starts at the first character after the first close# brace or after the function name and ends at the close brace.## A function name is the last word before an open parenthesis before# an open brace rather than a semicolon. It can appear at top level or# inside a class or interface block, but not inside a function block.## A function starts at the first character after the first close# brace or after the function name and ends at the close brace.## Comment handling is simple-minded but will work for all but pathological cases.## Result is a list of triples: [ start_line, end_line, function_name ].sub get_function_line_ranges_for_java($$){ my ($file_handle, $file_name) = @_; my @current_scopes; my @ranges; my $in_comment = 0; my $in_macro = 0; my $in_parentheses = 0; my $in_braces = 0; my $in_non_block_braces = 0; my $class_or_interface_just_seen = 0; my $word = ""; my $potential_start = 0; my $potential_name = ""; my $potential_name_is_class_or_interface = 0; my $start = 0; my $name = ""; my $current_name_is_class_or_interface = 0; while (<$file_handle>) { # Handle continued multi-line comment. if ($in_comment) { next unless s-.*\*/--; $in_comment = 0; } # Handle continued macro. if ($in_macro) { $in_macro = 0 unless /\\$/; next; } # Handle start of macro (or any preprocessor directive). if (/^\s*\#/) { $in_macro = 1 if /^([^\\]|\\.)*\\$/; next; } # Handle comments and quoted text. while (m-(/\*|//|\'|\")-) { # \' and \" keep emacs perl mode happy my $match = $1; if ($match eq "/*") { if (!s-/\*.*?\*/--) { s-/\*.*--; $in_comment = 1; } } elsif ($match eq "//") { s-//.*--; } else { # ' or " if (!s-$match([^\\]|\\.)*?$match--) { warn "mismatched quotes at line $. in $file_name\n"; s-$match.*--; } } } # Find function names. while (m-(\w+|[(){};])-g) { # Open parenthesis. if ($1 eq "(") { if (!$in_parentheses) { $potential_name = $word; $potential_name_is_class_or_interface = 0; } $in_parentheses++; next; } # Close parenthesis. if ($1 eq ")") { $in_parentheses--; next; } # Open brace. if ($1 eq "{") { # Promote potential name to real function name at the # start of the outer level set of braces (function/class/interface body?). if (!$in_non_block_braces and (!$in_braces or $current_name_is_class_or_interface) and $potential_start) { if ($name) { push @ranges, [ $start, ($. - 1), join ('.', @current_scopes) ]; } $current_name_is_class_or_interface = $potential_name_is_class_or_interface; $start = $potential_start; $name = $potential_name; push (@current_scopes, $name); } else { $in_non_block_braces++; } $potential_name = ""; $potential_start = 0; $in_braces++; next; } # Close brace. if ($1 eq "}") { $in_braces--; # End of an outer level set of braces. # This could be a function body. if (!$in_non_block_braces) { if ($name) { push @ranges, [ $start, $., join ('.', @current_scopes) ]; pop (@current_scopes); if (@current_scopes) { $current_name_is_class_or_interface = 1; $start = $. + 1; $name = $current_scopes[$#current_scopes-1]; } else { $current_name_is_class_or_interface = 0; $start = 0; $name = ""; } } } else { $in_non_block_braces-- if $in_non_block_braces; } $potential_start = 0; $potential_name = ""; next; } # Semicolon. if ($1 eq ";") { $potential_start = 0; $potential_name = ""; next; } if ($1 eq "class" or $1 eq "interface") { $class_or_interface_just_seen = 1; next; } # Word. $word = $1; if (!$in_parentheses) { if ($class_or_interface_just_seen) { $potential_name = $word; $potential_start = $.; $class_or_interface_just_seen = 0; $potential_name_is_class_or_interface = 1; next; } } if (!$potential_start) { $potential_start = $.; $potential_name = ""; } $class_or_interface_just_seen = 0; } } warn "mismatched braces in $file_name\n" if $in_braces; warn "mismatched parentheses in $file_name\n" if $in_parentheses; return @ranges;}# Read a file and get all the line ranges of the things that look like# JavaScript functions.## A function name is the word that immediately follows `function' when# followed by an open curly brace. It can appear at the top level, or# inside other functions.## An anonymous function name is the identifier chain immediately before# an assignment with the equals operator or object notation that has a# value starting with `function' followed by an open curly brace.## A getter or setter name is the word that immediately follows `get' or# `set' when followed by an open curly brace .## Comment handling is simple-minded but will work for all but pathological cases.## Result is a list of triples: [ start_line, end_line, function_name ].sub get_function_line_ranges_for_javascript($$){ my ($fileHandle, $fileName) = @_; my @currentScopes; my @currentIdentifiers; my @currentFunctionNames; my @currentFunctionDepths; my @currentFunctionStartLines; my @ranges; my $inComment = 0; my $inQuotedText = ""; my $parenthesesDepth = 0; my $bracesDepth = 0; my $functionJustSeen = 0; my $getterJustSeen = 0; my $setterJustSeen = 0; my $assignmentJustSeen = 0; my $word = ""; while (<$fileHandle>) { # Handle continued multi-line comment. if ($inComment) { next unless s-.*\*/--; $inComment = 0; } # Handle continued quoted text. if ($inQuotedText ne "") { next if /\\$/; s-([^\\]|\\.)*?$inQuotedText--; $inQuotedText = ""; } # Handle comments and quoted text. while (m-(/\*|//|\'|\")-) { # \' and \" keep emacs perl mode happy my $match = $1; if ($match eq '/*') { if (!s-/\*.*?\*/--) { s-/\*.*--; $inComment = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -