⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prepare-changelog.pl

📁 无线通信的主要编程软件,是无线通信工作人员的必备工具,关天相关教程我会在后续传上.
💻 PL
📖 第 1 页 / 共 2 页
字号:
#!/usr/bin/perl -w# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 2  -*-# Perl script to create a ChangeLog entry with names of files# and functions from a cvs diff.## Darin Adler <darin@eazel.com>, started 20 April 2000# Java support added by Maciej Stachowiak <mjs@eazel.com># last updated 28 December 2000## (Someone put a license in here, like maybe GPL.)## TODO:#   Provide option to put new ChangeLog into a separate file#     instead of editing the ChangeLog.#   For new files, just say "New file" instead of listing#     function names.#   List functions that have been removed too.#   Decide what a good logical order is for the changed files#     other than a normal text "sort" (top level first?)#     (group directories?) (.h before .c?)#   Leave a diff file behind if asked, but in unified format.#   Handle C++ and yacc source files too (other languages?).#   Help merge when there are ChangeLog conflicts or if there's#     already a partly written ChangeLog entry.#   Find appropriate ChangeLog to edit for each changed file#     instead of always using ChangeLog in current directory.#   Add command line option to put the ChangeLog into a separate#     file or just spew it out stdout.#   Figure out how to allow -z options from .cvsrc to work without#     letting other bad options work. Currently the -f disables#     everything from the .cvsrc.#   Add CVS version numbers for each file too (can't do that until#     the changes are checked in, though).#   Work around diff stupidity where deleting a function that starts#     with a comment makes diff think that the following function#     has been changed (if the following function starts with a comment#     with the same first line, such as /**)#   Work around diff stupidity where deleting an entire function and#     the blank lines before it makes diff think you've changed the#     previous function.## Modified to work with TinyOS in these ways:# - looks for the ChangeLog in ../../doc/ChangeLog# - looks for differences in .nc files as well as .c files#use diagnostics;use strict;use English;use Text::Wrap;## For TinyOS, we need to move to the the doc directory; we use # TOSDIR to do this. We only have one possible arg: -tosdir# -LKW#my $TOSDIR;my $i;$TOSDIR = "/opt/tinyos-1.x/tos";$TOSDIR = $ENV{"TOSDIR"} if defined($ENV{"TOSDIR"});for ($i = 0; $i <= $#ARGV; $i++) {    $_ = $ARGV[$i];    if (/^-/) {	if (/^-tosdir=(.*)/) {	    $TOSDIR = $1;	}    } }# Remove trailing / from TOSDIR, if any chop $TOSDIR if $TOSDIR =~ m!./$!;chdir "$TOSDIR/../doc";# Read the old change log file.# It's less efficient to read the whole thing into memory than it would be# to read it while we prepend to it later, but I like doing this part first.print STDERR "  Updating ChangeLog from cvs repository.\n";open ERRORS, "cvs update ChangeLog |" or die "The cvs update of ChangeLog failed: $OS_ERROR.\n";print STDERR "    $ARG" while <ERRORS>;close ERRORS;open OLD_CHANGE_LOG, "ChangeLog" or die "Could not open ChangeLog file: $OS_ERROR.\n";my @old_change_log = <OLD_CHANGE_LOG>;close OLD_CHANGE_LOG;# For each file, build a list of modified lines.# Use line numbers from the "after" side of each diff.print STDERR "  Running cvs diff to find changes.\n";my %changed_line_ranges;my $file;open DIFF, "cd ..; cvs -fq diff -N |" or die "The cvs diff failed: $OS_ERROR.\n";while (<DIFF>)  {    $file = $1 if /^Index: (\S+)/;    if (defined $file        and $file ne "ChangeLog")        #and (/^\d+(,\d+)?[acd](\d+)(,(\d+))?/ or /^Binary files/) )      {        push @{$changed_line_ranges{$file}}, [ $2, $4 || $2 ];      }  }close DIFF;if (!%changed_line_ranges)  {    print STDERR "  No changes found.\n";    exit;  }# For each ".c" file, convert line range to function list.print STDERR "  Extracting affected function names from C source files.\n";my %function_lists;foreach my $file (keys %changed_line_ranges)  {    # An empty function list still indicates that something changed.    $function_lists{$file} = "";    # Only look for function names in .c files.    next unless $file =~ /\.(c|java)/;    # Find all the functions in the file.    open SOURCE, $file or next;    my @function_ranges = get_function_line_ranges(\*SOURCE, $file);    close SOURCE;    # Find all the modified functions.    my @functions;    my %saw_function;    my @change_ranges = (@{$changed_line_ranges{$file}}, []);    my @change_range = (0, 0);    FUNCTION: foreach my $function_range_ref (@function_ranges)      {        my @function_range = @$function_range_ref;        # Advance to successive change ranges.        for (;; @change_range = @{shift @change_ranges})          {            last FUNCTION unless @change_range;            # If past this function, move on to the next one.            next FUNCTION if $change_range[0] > $function_range[1];                        # If an overlap with this function range, record the function name.            if ($change_range[1] >= $function_range[0]                and $change_range[0] <= $function_range[1])              {                if (!$saw_function{$function_range[2]})                  {                    $saw_function{$function_range[2]} = 1;                    push @functions, $function_range[2];                   }                next FUNCTION;              }          }      }    # Format the list of functions now.    $function_lists{$file} = " (" . join("), (", @functions) . "):" if @functions;  }# Write out a new ChangeLog file.print STDERR "  Editing the ChangeLog file.\n";my $date = sprintf "%d-%02d-%02d",  1900 + (localtime $BASETIME)[5], # year  1 + (localtime $BASETIME)[4], # month  (localtime $BASETIME)[3]; # day within monthmy $name = $ENV{CHANGE_LOG_NAME}  || $ENV{REAL_NAME}  || (getpwuid $REAL_USER_ID)[6]  || "set REAL_NAME environment variable";my $email_address = $ENV{CHANGE_LOG_EMAIL_ADDRESS}  || $ENV{EMAIL_ADDRESS}  || "set EMAIL_ADDRESS environment variable";open CHANGE_LOG, "> ChangeLog" or die "Could not write ChangeLog\n.";print CHANGE_LOG "$date  $name  <$email_address>\n\n";# LKW: took out because we don't review#print CHANGE_LOG "\treviewed by: <delete if not using a buddy>\n\n";foreach my $file (sort keys %function_lists)  {    my $lines = wrap("\t", "\t", "XX$file:$function_lists{$file}");    $lines =~ s/^\tXX/\t* /;    print CHANGE_LOG "$lines\n";  }print CHANGE_LOG "\n", @old_change_log;close CHANGE_LOG;# Done.print STDERR "  Done editing ChangeLog.\n";exit;sub get_function_line_ranges  {    my ($file_handle, $file_name) = @_;    if ($file_name =~ /\.c$/) {        return get_function_line_ranges_for_c ($file_handle, $file_name);    } elsif ($file_name =~ /\.java$/) {        return get_function_line_ranges_for_java ($file_handle, $file_name);    }    return ();  }# Read a file and get all the line ranges of the things that look like C functions.# A function name is the last word before an open parenthesis before the outer# level open brace. A function starts at the first character after the last close# brace or semicolon before 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_c  {    my ($file_handle, $file_name) = @_;    my @ranges;    my $in_comment = 0;    my $in_macro = 0;    my $in_parentheses = 0;    my $in_braces = 0;        my $word = "";    my $potential_start = 0;    my $potential_name = "";        my $start = 0;    my $name = "";        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 $INPUT_LINE_NUMBER in $file_name\n";                    s-$match.*--;                  }              }          }                # Find function names.        while (m-(\w+|[(){};])-g)          {            # Open parenthesis.            if ($1 eq "(")              {                $potential_name = $word unless $in_parentheses;                $in_parentheses++;                next;              }            # Close parenthesis.            if ($1 eq ")")              {                $in_parentheses--;                next;              }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -