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

📄 cvs2cl.pl

📁 linux下的E_MAIL客户端源码
💻 PL
📖 第 1 页 / 共 4 页
字号:
      if ($this_line =~ /\.$/)      {        $this_line .= "  ";        $length_remaining -= 2;      }      else  # not a sentence end      {        $this_line .= " ";        $length_remaining -= 1;      }    }    # Unconditionally indicate that loop has run at least once.    $first_time = 0;    $wrapped_text .= "${user_indent}${this_line}";  }  # One last bit of padding.  $wrapped_text .= "\n";  return $wrapped_text;}sub xml_escape (){  my $txt = shift;  $txt =~ s/&/&amp;/g;  $txt =~ s/</&lt;/g;  $txt =~ s/>/&gt;/g;  return $txt;}sub maybe_read_user_map_file (){  my %expansions;  if ($User_Map_File)  {    open (MAPFILE, "<$User_Map_File")        or die ("Unable to open $User_Map_File ($!)");    while (<MAPFILE>)     {      next if /^\s*#/;  # Skip comment lines.      next if not /:/;  # Skip lines without colons.      # It is now safe to split on ':'.      my ($username, $expansion) = split ':';      chomp $expansion;      $expansion =~ s/^'(.*)'$/$1/;      $expansion =~ s/^"(.*)"$/$1/;      # If it looks like the expansion has a real name already, then      # we toss the username we got from CVS log.  Otherwise, keep      # it to use in combination with the email address.      if ($expansion =~ /^\s*<{0,1}\S+@.*/) {        # Also, add angle brackets if none present        if (! ($expansion =~ /<\S+@\S+>/)) {          $expansions{$username} = "$username <$expansion>";        }        else {          $expansions{$username} = "$username $expansion";        }      }      else {        $expansions{$username} = $expansion;      }    }    close (MAPFILE);  }  return %expansions;}sub parse_options (){  # Check this internally before setting the global variable.  my $output_file;  # If this gets set, we encountered unknown options and will exit at  # the end of this subroutine.  my $exit_with_admonishment = 0;  while (my $arg = shift (@ARGV))   {    if ($arg =~ /^-h$|^-help$|^--help$|^--usage$|^-?$/) {      $Print_Usage = 1;    }    elsif ($arg =~ /^--debug$/) {        # unadvertised option, heh      $Debug = 1;    }    elsif ($arg =~ /^--version$/) {      $Print_Version = 1;    }    elsif ($arg =~ /^-g$|^--global-opts$/) {      my $narg = shift (@ARGV) || die "$arg needs argument.\n";      # Don't assume CVS is called "cvs" on the user's system:      $Log_Source_Command =~ s/(^\S*)/$1 $narg/;    }    elsif ($arg =~ /^-l$|^--log-opts$/) {      my $narg = shift (@ARGV) || die "$arg needs argument.\n";      $Log_Source_Command .= " $narg";    }    elsif ($arg =~ /^-f$|^--file$/) {      my $narg = shift (@ARGV) || die "$arg needs argument.\n";      $output_file = $narg;    }    elsif ($arg =~ /^--fsf$/) {      $FSF_Style = 1;    }    elsif ($arg =~ /^-U$|^--usermap$/) {      my $narg = shift (@ARGV) || die "$arg needs argument.\n";      $User_Map_File = $narg;    }    elsif ($arg =~ /^-W$|^--window$/) {      my $narg = shift (@ARGV) || die "$arg needs argument.\n";      $Max_Checkin_Duration = $narg;    }    elsif ($arg =~ /^-I$|^--ignore$/) {      my $narg = shift (@ARGV) || die "$arg needs argument.\n";      push (@Ignore_Files, $narg);    }    elsif ($arg =~ /^-C$|^--case-insensitive$/) {      $Case_Insensitive = 1;    }    elsif ($arg =~ /^-R$|^--regexp$/) {      my $narg = shift (@ARGV) || die "$arg needs argument.\n";      $Regexp_Gate = $narg;    }    elsif ($arg =~ /^--stdout$/) {      $Output_To_Stdout = 1;    }    elsif ($arg =~ /^--version$/) {      $Print_Version = 1;    }    elsif ($arg =~ /^-d$|^--distributed$/) {      $Distributed = 1;    }    elsif ($arg =~ /^-P$|^--prune$/) {      $Prune_Empty_Msgs = 1;    }    elsif ($arg =~ /^-S$|^--separate-header$/) {      $After_Header = "\n\n";    }    elsif ($arg =~ /^--no-wrap$/) {      $No_Wrap = 1;    }    elsif ($arg =~ /^--gmt$|^--utc$/) {      $UTC_Times = 1;    }    elsif ($arg =~ /^-w$|^--day-of-week$/) {      $Show_Day_Of_Week = 1;    }    elsif ($arg =~ /^-r$|^--revisions$/) {      $Show_Revisions = 1;    }    elsif ($arg =~ /^-t$|^--tags$/) {      $Show_Tags = 1;    }    elsif ($arg =~ /^-b$|^--branches$/) {      $Show_Branches = 1;    }    elsif ($arg =~ /^-F$|^--follow$/) {      my $narg = shift (@ARGV) || die "$arg needs argument.\n";      push (@Follow_Branches, $narg);    }    elsif ($arg =~ /^--stdin$/) {      $Input_From_Stdin = 1;    }    elsif ($arg =~ /^--header$/) {      my $narg = shift (@ARGV) || die "$arg needs argument.\n";      $ChangeLog_Header = &slurp_file ($narg);      if (! defined ($ChangeLog_Header)) {        $ChangeLog_Header = "";      }    }    elsif ($arg =~ /^--xml$/) {      $XML_Output = 1;    }    elsif ($arg =~ /^--hide-filenames$/) {      $Hide_Filenames = 1;      $After_Header = "";    }    else {      # Just add a filename as argument to the log command      $Log_Source_Command .= " $arg";    }  }  ## Check for contradictions...  if ($Output_To_Stdout && $Distributed) {    print STDERR "cannot pass both --stdout and --distributed\n";    $exit_with_admonishment = 1;  }  if ($Output_To_Stdout && $output_file) {    print STDERR "cannot pass both --stdout and --file\n";    $exit_with_admonishment = 1;  }  # Or if any other error message has already been printed out, we  # just leave now:  if ($exit_with_admonishment) {    &usage ();    exit (1);  }  elsif ($Print_Usage) {    &usage ();    exit (0);  }  elsif ($Print_Version) {    &version ();    exit (0);  }  ## Else no problems, so proceed.  if ($Output_To_Stdout) {    undef $Log_File_Name;       # not actually necessary  }  elsif ($output_file) {    $Log_File_Name = $output_file;  }}sub slurp_file (){  my $filename = shift || die ("no filename passed to slurp_file()");  my $retstr;  open (SLURPEE, "<${filename}") or die ("unable to open $filename ($!)");  my $saved_sep = $/;  undef $/;  $retstr = <SLURPEE>;  $/ = $saved_sep;  close (SLURPEE);  return $retstr;}sub debug (){  if ($Debug) {    my $msg = shift;    print STDERR $msg;  }}sub version (){  print "cvs2cl.pl version ${VERSION}; distributed under the GNU GPL.\n";}sub usage (){  &version ();  print <<'END_OF_INFO';Generate GNU-style ChangeLogs in CVS working copies.Notes about the output format(s):   The default output of cvs2cl.pl is designed to be compact, formally   unambiguous, but still easy for humans to read.  It is largely   self-explanatory, I hope; the one abbreviation that might not be   obvious is "utags".  That stands for "universal tags" -- a   universal tag is one held by all the files in a given change entry.   If you need output that's easy for a program to parse, use the   --xml option.  Note that with XML output, just about all available   information is included with each change entry, whether you asked   for it or not, on the theory that your parser can ignore anything   it's not looking for.Notes about the options and arguments (the actual options are listedlast in this usage message):  * The -I and -F options may appear multiple times.  * To follow trunk revisions, use "-F trunk" ("-F TRUNK" also works).    This is okay because no would ever, ever be crazy enough to name a    branch "trunk", right?  Right.  * For the -U option, the UFILE should be formatted like    CVSROOT/users. That is, each line of UFILE looks like this       jrandom:jrandom@red-bean.com    or maybe even like this       jrandom:'Jesse Q. Random <jrandom@red-bean.com>'    Don't forget to quote the portion after the colon if necessary.    * Many people want to filter by date.  To do so, invoke cvs2cl.pl    like this:        cvs2cl.pl -l "-d'DATESPEC'"    where DATESPEC is any date specification valid for "cvs log -d".    (Note that CVS 1.10.7 and below requires there be no space between    -d and its argument).Options/Arguments:  -h, -help, --help, or -?     Show this usage and exit  --version                    Show version and exit  -r, --revisions              Show revision numbers in output  -b, --branches               Show branch names in revisions when possible  -t, --tags                   Show tags (symbolic names) in output  --stdin                      Read from stdin, don't run cvs log  --stdout                     Output to stdout not to ChangeLog  -d, --distributed            Put ChangeLogs in subdirs  -f FILE, --file FILE         Write to FILE instead of "ChangeLog"  --fsf                        Use this if log data is in FSF ChangeLog style  -W SECS, --window SECS       Window of time within which log entries unify  -U UFILE, --usermap UFILE    Expand usernames to email addresses from UFILE  -R REGEXP, --regexp REGEXP   Include only entries that match REGEXP  -I REGEXP, --ignore REGEXP   Ignore files whose names match REGEXP  -C, --case-insensitive       Any regexp matching is done case-insensitively  -F BRANCH, --follow BRANCH   Show only revisions on or ancestral to BRANCH  -S, --separate-header        Blank line between each header and log message  --no-wrap                    Don't auto-wrap log message (recommend -S also)  --gmt, --utc                 Show times in GMT/UTC instead of local time  -w, --day-of-week            Show day of week  --header FILE                Get ChangeLog header from FILE ("-" means stdin)  --xml                        Output XML instead of ChangeLog format  --hide-filenames             Don't show filenames (ignored for XML output)  -P, --prune                  Don't show empty log messages  -g OPTS, --global-opts OPTS  Invoke like this "cvs OPTS log ..."  -l OPTS, --log-opts OPTS     Invoke like this "cvs ... log OPTS"  FILE1 [FILE2 ...]            Show only log information for the named FILE(s)See http://www.red-bean.com/cvs2cl for maintenance and bug info.END_OF_INFO}__END__=head1 NAMEcvs2cl.pl - produces GNU-style ChangeLogs in CVS working copies, by    running "cvs log" and parsing the output.  Shared log entries are    unified in an intuitive way.=head1 DESCRIPTIONThis script generates GNU-style ChangeLog files from CVS loginformation.  Basic usage: just run it inside a working copy and aChangeLog will appear.  It requires repository access (i.e., 'cvs log'must work).  Run "cvs2cl.pl --help" to see more advanced options.See http://www.red-bean.com/cvs2cl for updates, and for instructionson getting anonymous CVS access to this script.Maintainer: Karl Fogel <kfogel@red-bean.com>Please report bugs to <bug-cvs2cl@red-bean.com>.=head1 READMEThis script generates GNU-style ChangeLog files from CVS loginformation.  Basic usage: just run it inside a working copy and aChangeLog will appear.  It requires repository access (i.e., 'cvs log'must work).  Run "cvs2cl.pl --help" to see more advanced options.See http://www.red-bean.com/cvs2cl for updates, and for instructionson getting anonymous CVS access to this script.Maintainer: Karl Fogel <kfogel@red-bean.com>Please report bugs to <bug-cvs2cl@red-bean.com>.=head1 PREREQUISITESThis script requires C<Text::Wrap>, C<Time::Local>, andC<File::Basename>.It also seems to require C<Perl 5.004_04> or higher.=pod OSNAMESany=pod SCRIPT CATEGORIESVersion_Control/CVS=cut-*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*-Note about a bug-slash-opportunity:-----------------------------------There's a bug in Text::Wrap, which affects cvs2cl.  This scriptreveals it:  #!/usr/bin/perl -w    use Text::Wrap;    my $test_text =  "This script demonstrates a bug in Text::Wrap.  The very long line  following this paragraph will be relocated relative to the surrounding  text:    ====================================================================    See?  When the bug happens, we'll get the line of equal signs below  this paragraph, even though it should be above.";      # Print out the test text with no wrapping:  print "$test_text";  print "\n";  print "\n";    # Now print it out wrapped, and see the bug:  print wrap ("\t", "        ", "$test_text");  print "\n";  print "\n";If the line of equal signs were one shorter, then the bug doesn'thappen.  Interesting.Anyway, rather than fix this in Text::Wrap, we might as well write anew wrap() which has the following much-needed features:* initial indentation, like current Text::Wrap()* subsequent line indentation, like current Text::Wrap()* user chooses among: force-break long words, leave them alone, or die()?* preserve existing indentation: chopped chunks from an indented line  are indented by same (like this line, not counting the asterisk!)* optional list of things to preserve on line starts, default ">"Note that the last two are essentially the same concept, so unify inimplementation and give a good interface to controlling them.And how about:Optionally, when encounter a line pre-indented by same as previousline, then strip the newline and refill, but indent by the same.Yeah...

⌨️ 快捷键说明

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