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

📄 cvs2cl.pl

📁 xgrafix 是PTSG模拟程序中的图形截面库 改版本是最新版本
💻 PL
📖 第 1 页 / 共 5 页
字号:
      $utag = $self->escape($utag);   # the usual paranoia      $beauty .= "<utag>${utag}</utag>\n";    }  }  if ($common_dir) {    $common_dir = $self->escape($common_dir);    $beauty .= "<commondir>${common_dir}</commondir>\n";  }  # That's enough for XML, time to go home:  return $beauty;}# -------------------------------------sub output_tagdate {  # NOT YET DONE}# -------------------------------------sub output_entry {  my $self = shift;  my ($fh, $entry) = @_;  print $fh "<entry>\n$entry</entry>\n\n";}# -------------------------------------sub format_body {  my $self = shift;  my ($msg, $files, $qunklist) = @_;  $msg = $self->preprocess_msg_text($msg);  return $files . $msg;}# ----------------------------------------------------------------------------package CVS::Utils::ChangeLog::EntrySet::Output;use Carp           qw( croak );use File::Basename qw( fileparse );# Class Utility Functions -------------{ # form closuremy @weekdays = (qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday));sub weekday_en {  my $class = shift;  return $weekdays[$_[0]];}}# Abstract Subrs ----------------------sub wday               { croak "Whoops.  Abtract method call (wday).\n" }sub pretty_file_list   { croak "Whoops.  Abtract method call (pretty_file_list).\n" }sub output_tagdate     { croak "Whoops.  Abtract method call (output_tagdate).\n" }sub header_line        { croak "Whoops.  Abtract method call (header_line).\n" }# Instance Subrs ----------------------sub output_header { }# -------------------------------------sub output_entry {  my $self = shift;  my ($fh, $entry) = @_;  print $fh "$entry\n";}# -------------------------------------sub output_footer { }# -------------------------------------sub escape { return $_[1] }# -------------------------------------sub output_changelog {my $self = shift; my $class = ref $self;  my ($grand_poobah) = @_;  ### Process each ChangeLog  while (my ($dir,$authorhash) = each %$grand_poobah)  {    &main::debug ("DOING DIR: $dir\n");    # Here we twist our hash around, from being    #   author => time => message => filelist    # in %$authorhash to    #   time => author => message => filelist    # in %changelog.    #    # This is also where we merge entries.  The algorithm proceeds    # through the timeline of the changelog with a sliding window of    # $Max_Checkin_Duration seconds; within that window, entries that    # have the same log message are merged.    #    # (To save space, we zap %$authorhash after we've copied    # everything out of it.)    my %changelog;    while (my ($author,$timehash) = each %$authorhash)    {      my %stamptime;      foreach my $time (sort {$a <=> $b} (keys %$timehash))      {        my $msghash = $timehash->{$time};        while (my ($msg,$qunklist) = each %$msghash)        {          my $stamptime = $stamptime{$msg};          if ((defined $stamptime)              and (($time - $stamptime) < $Max_Checkin_Duration)              and (defined $changelog{$stamptime}{$author}{$msg}))          {            push(@{$changelog{$stamptime}{$author}{$msg}}, $qunklist->files);          }          else {            $changelog{$time}{$author}{$msg} = $qunklist->files;            $stamptime{$msg} = $time;          }        }      }    }    undef (%$authorhash);    ### Now we can write out the ChangeLog!    my ($logfile_here, $logfile_bak, $tmpfile);    my $lastdate;    if (! $Output_To_Stdout) {      $logfile_here =  $dir . $Log_File_Name;      $logfile_here =~ s/^\.\/\//\//;   # fix any leading ".//" problem      $tmpfile      = "${logfile_here}.cvs2cl$$.tmp";      $logfile_bak  = "${logfile_here}.bak";      open (LOG_OUT, ">$tmpfile") or die "Unable to open \"$tmpfile\"";    }    else {      open (LOG_OUT, ">-") or die "Unable to open stdout for writing";    }    print LOG_OUT $ChangeLog_Header;    my %tag_date_printed;    $self->output_header(\*LOG_OUT);    my @key_list = ();    if($Chronological_Order) {        @key_list = sort {$a <=> $b} (keys %changelog);    } else {        @key_list = sort {$b <=> $a} (keys %changelog);    }    foreach my $time (@key_list)    {      next if ($Delta_Mode &&               (($time <= $Delta_StartTime) ||                ($time > $Delta_EndTime && $Delta_EndTime)));      # Set up the date/author line.      # kff todo: do some more XML munging here, on the header      # part of the entry:      my (undef,$min,$hour,$mday,$mon,$year,$wday)          = $UTC_Times ? gmtime($time) : localtime($time);      $wday = $self->wday($wday);      # XML output includes everything else, we might as well make      # it always include Day Of Week too, for consistency.      my $authorhash = $changelog{$time};      if ($Show_Tag_Dates) {        my %tags;        while (my ($author,$mesghash) = each %$authorhash) {          while (my ($msg,$qunk) = each %$mesghash) {            foreach my $qunkref2 (@$qunk) {              if (defined ($qunkref2->tags)) {                foreach my $tag (@{$qunkref2->tags}) {                  $tags{$tag} = 1;                }              }            }          }        }        # Sort here for determinism to ease testing        foreach my $tag (sort keys %tags) {          if ( ! defined $tag_date_printed{$tag} ) {            $tag_date_printed{$tag} = $time;            $self->output_tagdate(\*LOG_OUT, $time, $tag);          }        }      }      while (my ($author,$mesghash) = each %$authorhash)      {        # If XML, escape in outer loop to avoid compound quoting:        $author = $self->escape($author);      FOOBIE:        # We sort here to enable predictable ordering for the testing porpoises        for my $msg (sort keys %$mesghash)        {          my $qunklist = $mesghash->{$msg};          ## MJP: 19.xii.01 : Exclude @ignore_tags          for my $ignore_tag (keys %ignore_tags) {            next FOOBIE              if grep($_ eq $ignore_tag, map(@{$_->{tags}},                                             grep(defined $_->{tags},                                                  @$qunklist)));          }          ## MJP: 19.xii.01 : End exclude @ignore_tags          # show only files with tag --show-tag $show_tag          if ( keys %show_tags ) {            next FOOBIE              if !grep(exists $show_tags{$_}, map(@{$_->{tags}},                                                  grep(defined $_->{tags},                                                       @$qunklist)));          }          my $files               = $self->pretty_file_list($qunklist);          my $header_line;          # date and author          my $wholething;           # $header_line + $body          my $date = $self->fdatetime($time);          $header_line = $self->header_line($time, $author, $lastdate);          $lastdate = $date;          $Text::Wrap::huge = 'overflow'            if $Text::Wrap::VERSION >= 2001.0130;          # Reshape the body according to user preferences.          my $body = $self->format_body($msg, $files, $qunklist);          $body =~ s/[ \t]+\n/\n/g;          $wholething = $header_line . $body;          # One last check: make sure it passes the regexp test, if the          # user asked for that.  We have to do it here, so that the          # test can match against information in the header as well          # as in the text of the log message.          # How annoying to duplicate so much code just because I          # can't figure out a way to evaluate scalars on the trailing          # operator portion of a regular expression.  Grrr.          if ($Case_Insensitive) {            unless ( $Regexp_Gate and ( $wholething !~ /$Regexp_Gate/oi ) ) {              $self->output_entry(\*LOG_OUT, $wholething);            }          }          else {            unless ( $Regexp_Gate and ( $wholething !~ /$Regexp_Gate/o ) ) {              $self->output_entry(\*LOG_OUT, $wholething);            }          }        }      }    }    $self->output_footer(\*LOG_OUT);    close (LOG_OUT);    if ( ! $Output_To_Stdout ) {      # If accumulating, append old data to new before renaming.  But      # don't append the most recent entry, since it's already in the      # new log due to CVS's idiosyncratic interpretation of "log -d".      if ($Cumulative && -f $logfile_here) {        open NEW_LOG, ">>$tmpfile"          or die "trouble appending to $tmpfile ($!)";        open OLD_LOG, "<$logfile_here"          or die "trouble reading from $logfile_here ($!)";        my $started_first_entry = 0;        my $passed_first_entry = 0;        while (<OLD_LOG>) {          if ( ! $passed_first_entry ) {            if ( ( ! $started_first_entry )                and /^(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d)/ ) {              $started_first_entry = 1;            } elsif ( /^(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d)/ ) {              $passed_first_entry = 1;              print NEW_LOG $_;            }          } else {            print NEW_LOG $_;          }        }        close NEW_LOG;        close OLD_LOG;      }      if ( -f $logfile_here ) {        rename $logfile_here, $logfile_bak;      }      rename $tmpfile, $logfile_here;    }  }}# -------------------------------------# Don't call this wrap, because with 5.5.3, that clashes with the# (unconditional :-( ) export of wrap() from Text::Wrapsub mywrap {  my $self = shift;  my ($indent1, $indent2, @text) = @_;  # If incoming text looks preformatted, don't get clever  my $text = Text::Wrap::wrap($indent1, $indent2, @text);  if ( grep /^\s+/m, @text ) {    return $text;  }  my @lines = split /\n/, $text;  $indent2 =~ s!^((?: {8})+)!"\t" x (length($1)/8)!e;  $lines[0] =~ s/^$indent1\s+/$indent1/;  s/^$indent2\s+/$indent2/    for @lines[1..$#lines];  my $newtext = join "\n", @lines;  $newtext .= "\n"    if substr($text, -1) eq "\n";  return $newtext;}# -------------------------------------sub preprocess_msg_text {  my $self = shift;  my ($text) = @_;  # Strip out carriage returns (as they probably result from DOSsy editors).  $text =~ s/\r\n/\n/g;  # If it *looks* like two newlines, make it *be* two newlines:  $text =~ s/\n\s*\n/\n\n/g;  return $text;}# -------------------------------------sub last_line_len {  my $self = shift;  my $files_list = shift;  my @lines = split (/\n/, $files_list);  my $last_line = pop (@lines);  return length ($last_line);}# -------------------------------------# A custom wrap function, sensitive to some common constructs used in# log entries.sub wrap_log_entry {  my $self = shift;  my $text = shift;                  # The text to wrap.  my $left_pad_str = shift;          # String to pad with on the left.  # These do NOT take left_pad_str into account:  my $length_remaining = shift;      # Amount left on current line.  my $max_line_length  = shift;      # Amount left for a blank line.  my $wrapped_text = '';             # The accumulating wrapped entry.  my $user_indent = '';              # Inherited user_indent from prev line.  my $first_time = 1;                # First iteration of the loop?  my $suppress_line_start_match = 0; # Set to disable line start checks.  my @lines = split (/\n/, $text);  while (@lines)   # Don't use `foreach' here, it won't work.  {    my $this_line = shift (@lines);    chomp $this_line;    if ($this_line =~ /^(\s+)/) {      $user_indent = $1;    }    else {      $user_indent = '';    }    # If it matches any of the line-start regexps, print a newline now...    if ($suppress_line_start_match)    {      $suppress_line_start_match = 0;    }    elsif (($this_line =~ /^(\s*)\*\s+[a-zA-Z0-9]/)           || ($this_line =~ /^(\s*)\* [a-zA-Z0-9_\.\/\+-]+/)           || ($this_line =~ /^(\s*)\([a-zA-Z0-9_\.\/\+-]+(\)|,\s*)/)           || ($this_line =~ /^(\s+)(\S+)/)           || ($this_line =~ /^(\s*)- +/)           || ($this_line =~ /^()\s*$/)           || ($this_line =~ /^(\s*)\*\) +/)           || ($this_line =~ /^(\s*)[a-zA-Z0-9](\)|\.|\:) +/))    {      # Make a line break immediately, unless header separator is set      # and this line is the first line in the entry, in which case      # we're getting the blank line for free already and shouldn't      # add an extra one.      unless (($After_Header ne " ") and ($first_time))      {        if ($this_line =~ /^()\s*$/) {          $suppress_line_start_match = 1;          $wrapped_text .= "\n${left_pad_str}";        }        $wrapped_text .= "\n${left_pad_str}";      }      $length_remaining = $max_line_length - (length ($user_indent));    }    # Now that any user_indent has been preserved, strip off leading    # whitespace, so up-folding has no ugly side-effects.    $this_line =~ s/^\s*//;    # Accumulate the line, and adjust parameters for next line.    my $this_len = length ($this_line);    if ($this_len == 0)    {      # Blank lines should cancel any user_indent level.      $user_indent = '';      $length_remaining = $max_line_length;    }    elsif ($this_len >= $length_remaining) # Line too long, try breaking it.    {      # Walk backwards from the end.  At first acceptable spot, break      # a new line.      my $idx = $length_remaining - 1;      if ($idx < 0) { $idx = 0 };      while ($idx > 0)      {        if (substr ($this_line, $idx, 1) =~ /\s/)        {          my $line_now = substr ($this_line, 0, $idx);          my $next_line = substr ($this_line, $idx);          $this_line = $line_now;          # Clean whitespace off the end.          chomp $this_line;

⌨️ 快捷键说明

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