← Index
NYTProf Performance Profile   « block view • line view • sub view »
For /usr/local/src/github.com/foswiki/core/bin/view
  Run on Sun Dec 4 17:17:59 2011
Reported on Sun Dec 4 17:26:33 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/VC/RcsWrapHandler.pm
StatementsExecuted 885 statements in 15.0ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1119.58ms16.3msFoswiki::Store::VC::RcsWrapHandler::::BEGIN@22Foswiki::Store::VC::RcsWrapHandler::BEGIN@22
347114.95ms25.0msFoswiki::Store::VC::RcsWrapHandler::::newFoswiki::Store::VC::RcsWrapHandler::new
21112.44ms92.8sFoswiki::Store::VC::RcsWrapHandler::::getInfoFoswiki::Store::VC::RcsWrapHandler::getInfo
33321.71ms46.6sFoswiki::Store::VC::RcsWrapHandler::::_numRevisionsFoswiki::Store::VC::RcsWrapHandler::_numRevisions
70111.32ms12.1msFoswiki::Store::VC::RcsWrapHandler::::getRevisionFoswiki::Store::VC::RcsWrapHandler::getRevision
5731568µs568µsFoswiki::Store::VC::RcsWrapHandler::::CORE:matchFoswiki::Store::VC::RcsWrapHandler::CORE:match (opcode)
4821193µs193µsFoswiki::Store::VC::RcsWrapHandler::::CORE:ftisFoswiki::Store::VC::RcsWrapHandler::CORE:ftis (opcode)
11125µs32µsFoswiki::Store::VC::RcsWrapHandler::::BEGIN@19Foswiki::Store::VC::RcsWrapHandler::BEGIN@19
11117µs37µsFoswiki::Store::VC::RcsWrapHandler::::BEGIN@20Foswiki::Store::VC::RcsWrapHandler::BEGIN@20
11111µs11µsFoswiki::Store::VC::RcsWrapHandler::::BEGIN@25Foswiki::Store::VC::RcsWrapHandler::BEGIN@25
0000s0sFoswiki::Store::VC::RcsWrapHandler::::_deleteRevisionFoswiki::Store::VC::RcsWrapHandler::_deleteRevision
0000s0sFoswiki::Store::VC::RcsWrapHandler::::_lockFoswiki::Store::VC::RcsWrapHandler::_lock
0000s0sFoswiki::Store::VC::RcsWrapHandler::::ciFoswiki::Store::VC::RcsWrapHandler::ci
0000s0sFoswiki::Store::VC::RcsWrapHandler::::deleteRevisionFoswiki::Store::VC::RcsWrapHandler::deleteRevision
0000s0sFoswiki::Store::VC::RcsWrapHandler::::finishFoswiki::Store::VC::RcsWrapHandler::finish
0000s0sFoswiki::Store::VC::RcsWrapHandler::::getRevisionAtTimeFoswiki::Store::VC::RcsWrapHandler::getRevisionAtTime
0000s0sFoswiki::Store::VC::RcsWrapHandler::::initBinaryFoswiki::Store::VC::RcsWrapHandler::initBinary
0000s0sFoswiki::Store::VC::RcsWrapHandler::::initTextFoswiki::Store::VC::RcsWrapHandler::initText
0000s0sFoswiki::Store::VC::RcsWrapHandler::::parseRevisionDiffFoswiki::Store::VC::RcsWrapHandler::parseRevisionDiff
0000s0sFoswiki::Store::VC::RcsWrapHandler::::repRevFoswiki::Store::VC::RcsWrapHandler::repRev
0000s0sFoswiki::Store::VC::RcsWrapHandler::::revisionDiffFoswiki::Store::VC::RcsWrapHandler::revisionDiff
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2
3=begin TML
4
5---+ package Foswiki::Store::VC::RcsWrapHandler
6
7This class implements the pure methods of the Foswiki::Store::VC::Handler
8superclass. See the superclass for detailed documentation of the methods.
9
10Wrapper around the RCS commands required by Foswiki.
11An object of this class is created for each file stored under RCS.
12
13For readers who are familiar with Foswiki version 1.0, this class
14is analagous to the old =Foswiki::Store::RcsWrap=.
15
16=cut
17
18package Foswiki::Store::VC::RcsWrapHandler;
19246µs239µs
# spent 32µs (25+7) within Foswiki::Store::VC::RcsWrapHandler::BEGIN@19 which was called: # once (25µs+7µs) by Foswiki::Store::RcsWrap::BEGIN@26 at line 19
use strict;
# spent 32µs making 1 call to Foswiki::Store::VC::RcsWrapHandler::BEGIN@19 # spent 7µs making 1 call to strict::import
20255µs257µs
# spent 37µs (17+20) within Foswiki::Store::VC::RcsWrapHandler::BEGIN@20 which was called: # once (17µs+20µs) by Foswiki::Store::RcsWrap::BEGIN@26 at line 20
use warnings;
# spent 37µs making 1 call to Foswiki::Store::VC::RcsWrapHandler::BEGIN@20 # spent 20µs making 1 call to warnings::import
21
222200µs116.3ms
# spent 16.3ms (9.58+6.69) within Foswiki::Store::VC::RcsWrapHandler::BEGIN@22 which was called: # once (9.58ms+6.69ms) by Foswiki::Store::RcsWrap::BEGIN@26 at line 22
use Foswiki::Store::VC::Handler ();
# spent 16.3ms making 1 call to Foswiki::Store::VC::RcsWrapHandler::BEGIN@22
23112µsour @ISA = ('Foswiki::Store::VC::Handler');
24
2523.88ms111µs
# spent 11µs within Foswiki::Store::VC::RcsWrapHandler::BEGIN@25 which was called: # once (11µs+0s) by Foswiki::Store::RcsWrap::BEGIN@26 at line 25
use Foswiki::Sandbox ();
# spent 11µs making 1 call to Foswiki::Store::VC::RcsWrapHandler::BEGIN@25
26
27
# spent 25.0ms (4.95+20.0) within Foswiki::Store::VC::RcsWrapHandler::new which was called 347 times, avg 72µs/call: # 347 times (4.95ms+20.0ms) by Foswiki::Store::RcsWrap::getHandler at line 30 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/RcsWrap.pm, avg 72µs/call
sub new {
283474.84ms34720.0ms return shift->SUPER::new(@_);
# spent 20.0ms making 347 calls to Foswiki::Store::VC::Handler::new, avg 58µs/call
29}
30
31=begin TML
32
33---++ ObjectMethod finish()
34Break circular references.
35
36=cut
37
38# Note to developers; please undef *all* fields in the object explicitly,
39# whether they are references or not. That way this method is "golden
40# documentation" of the live fields in the object.
41sub finish {
42 my $this = shift;
43 $this->SUPER::finish();
44 undef $this->{binary};
45}
46
47# implements VC::Handler
48sub initBinary {
49 my ($this) = @_;
50
51 $this->{binary} = 1;
52
53 $this->mkPathTo( $this->{file} );
54
55 return if -e $this->{rcsFile};
56
57 my ( $rcsOutput, $exit ) =
58 Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{initBinaryCmd},
59 FILENAME => $this->{file} );
60 if ($exit) {
61 throw Error::Simple( $Foswiki::cfg{RCS}{initBinaryCmd} . ' of '
62 . $this->hidePath( $this->{file} )
63 . ' failed: '
64 . $rcsOutput );
65 }
66 elsif ( !-e $this->{rcsFile} ) {
67
68 # Sometimes (on Windows?) rcs file not formed, so check for it
69 throw Error::Simple( $Foswiki::cfg{RCS}{initBinaryCmd} . ' of '
70 . $this->hidePath( $this->{rcsFile} )
71 . ' failed to create history file' );
72 }
73}
74
75# implements VC::Handler
76sub initText {
77 my ($this) = @_;
78 $this->{binary} = 0;
79
80 $this->mkPathTo( $this->{file} );
81
82 return if -e $this->{rcsFile};
83
84 my ( $rcsOutput, $exit ) =
85 Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{initTextCmd},
86 FILENAME => $this->{file} );
87 if ($exit) {
88 $rcsOutput ||= '';
89 throw Error::Simple( $Foswiki::cfg{RCS}{initTextCmd} . ' of '
90 . $this->hidePath( $this->{file} )
91 . ' failed: '
92 . $rcsOutput );
93 }
94 elsif ( !-e $this->{rcsFile} ) {
95
96 # Sometimes (on Windows?) rcs file not formed, so check for it
97 throw Error::Simple( $Foswiki::cfg{RCS}{initTextCmd} . ' of '
98 . $this->hidePath( $this->{rcsFile} )
99 . ' failed to create history file' );
100 }
101}
102
103# implements VC::Handler
104
105# Designed for calling *only* from the Handler superclass and this class
106sub ci {
107 my ( $this, $isStream, $data, $comment, $user, $date ) = @_;
108
109 _lock($this);
110 if ($isStream) {
111 $this->saveStream($data);
112 }
113 else {
114 $this->saveFile( $this->{file}, $data );
115 }
116
117 $comment = 'none' unless $comment;
118
119 my ( $cmd, $rcsOutput, $exit );
120 if ( defined($date) ) {
121 require Foswiki::Time;
122 $date = Foswiki::Time::formatTime( $date, '$rcs', 'gmtime' );
123 $cmd = $Foswiki::cfg{RCS}{ciDateCmd};
124 ( $rcsOutput, $exit ) = Foswiki::Sandbox->sysCommand(
125 $cmd,
126 USERNAME => $user,
127 FILENAME => $this->{file},
128 COMMENT => $comment,
129 DATE => $date
130 );
131 }
132 else {
133 $cmd = $Foswiki::cfg{RCS}{ciCmd};
134 ( $rcsOutput, $exit ) = Foswiki::Sandbox->sysCommand(
135 $cmd,
136 USERNAME => $user,
137 FILENAME => $this->{file},
138 COMMENT => $comment
139 );
140 }
141 $rcsOutput ||= '';
142
143 if ($exit) {
144 throw Error::Simple( $cmd . ' of '
145 . $this->hidePath( $this->{file} )
146 . ' failed: '
147 . $exit . ' '
148 . $rcsOutput );
149 }
150
151 chmod( $Foswiki::cfg{RCS}{filePermission}, $this->{file} );
152}
153
154# implements VC::Handler
155sub repRev {
156 my ( $this, $text, $comment, $user, $date ) = @_;
157
158 my $rev = $this->_numRevisions() || 0;
159
160 $comment ||= 'none';
161
162 # update repository with same userName and date
163 if ( $rev <= 1 ) {
164
165 # initial revision, so delete repository file and start again
166 unlink $this->{rcsFile};
167 }
168 else {
169 _deleteRevision( $this, $rev );
170 }
171
172 Foswiki::Store::VC::Handler::saveFile( $this, $this->{file}, $text );
173 require Foswiki::Time;
174 $date = Foswiki::Time::formatTime( $date, '$rcs', 'gmtime' );
175
176 _lock($this);
177 my ( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
178 $Foswiki::cfg{RCS}{ciDateCmd},
179 DATE => $date,
180 USERNAME => $user,
181 FILENAME => $this->{file},
182 COMMENT => $comment
183 );
184 if ($exit) {
185 $rcsOut = $Foswiki::cfg{RCS}{ciDateCmd} . "\n" . $rcsOut;
186 return $rcsOut;
187 }
188 chmod( $Foswiki::cfg{RCS}{filePermission}, $this->{file} );
189}
190
191# implements VC::Handler
192sub deleteRevision {
193 my ($this) = @_;
194 my $rev = $this->_numRevisions();
195 return if ( $rev <= 1 );
196 return _deleteRevision( $this, $rev );
197}
198
199sub _deleteRevision {
200 my ( $this, $rev ) = @_;
201
202 # delete latest revision (unlock (may not be needed), delete revision)
203 my ( $rcsOut, $exit ) =
204 Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{unlockCmd},
205 FILENAME => $this->{file} );
206 if ($exit) {
207 throw Error::Simple(
208 $Foswiki::cfg{RCS}{unlockCmd} . ' failed: ' . $rcsOut );
209 }
210
211 chmod( $Foswiki::cfg{RCS}{filePermission}, $this->{file} );
212
213 ( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
214 $Foswiki::cfg{RCS}{delRevCmd},
215 REVISION => '1.' . $rev,
216 FILENAME => $this->{file}
217 );
218
219 if ($exit) {
220 throw Error::Simple( $Foswiki::cfg{RCS}{delRevCmd} . ' of '
221 . $this->hidePath( $this->{file} )
222 . ' failed: '
223 . $rcsOut );
224 }
225
226 # Update the checkout
227 $rev--;
228 ( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
229 $Foswiki::cfg{RCS}{coCmd},
230 REVISION => '1.' . $rev,
231 FILENAME => $this->{file}
232 );
233
234 if ($exit) {
235 throw Error::Simple( $Foswiki::cfg{RCS}{coCmd} . ' of '
236 . $this->hidePath( $this->{file} )
237 . ' failed: '
238 . $rcsOut );
239 }
240 Foswiki::Store::VC::Handler::saveFile( $this, $this->{file}, $rcsOut );
241}
242
243# implements VC::Handler
244
# spent 12.1ms (1.32+10.8) within Foswiki::Store::VC::RcsWrapHandler::getRevision which was called 70 times, avg 173µs/call: # 70 times (1.32ms+10.8ms) by Foswiki::Store::VC::Store::readTopic at line 103 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/VC/Store.pm, avg 173µs/call
sub getRevision {
2452101.23ms my ( $this, $version ) = @_;
246
247 unless ( $version && -e $this->{rcsFile} ) {
248
249 # Get the latest rev from the cache
2507010.8ms return ( $this->SUPER::getRevision($version) );
# spent 10.8ms making 70 calls to Foswiki::Store::VC::Handler::getRevision, avg 154µs/call
251 }
252
253 # We've been asked for an explicit rev. The rev might be outside the
254 # range of revs in RCS. RCS will return the latest, though it reports
255 # the rev retrieved to STDERR (no use to us, as we have no access
256 # to STDERR)
257
258 # SMELL: we need to determine if the rev we are returning is the latest.
259 # co prints the retrieved revision, but unfortunately it prints it
260 # to STDERR, which the Sandbox can't retrieve.
261
262 my $tmpfile;
263 my $tmpRevFile;
264 my $coCmd = $Foswiki::cfg{RCS}{coCmd};
265 my $file = $this->{file};
266 if ( $Foswiki::cfg{RCS}{coMustCopy} ) {
267
268 # Need to take temporary copy of topic, check it out to file,
269 # then read that. Need to put RCS into binary mode to avoid
270 # extra \r appearing and read from binmode file rather than
271 # stdout to avoid early file read termination
272 # See http://twiki.org/cgi-bin/view/Codev/DakarRcsWrapProblem
273 # for evidence that this code is needed.
274 $tmpfile = Foswiki::Store::VC::Handler::mkTmpFilename($this);
275 $tmpRevFile = $tmpfile . ',v';
276 require File::Copy;
277 File::Copy::copy( $this->{rcsFile}, $tmpRevFile );
278 my ( $rcsOutput, $status ) =
279 Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{tmpBinaryCmd},
280 FILENAME => $tmpRevFile );
281 if ($status) {
282 throw Error::Simple(
283 $Foswiki::cfg{RCS}{tmpBinaryCmd} . ' failed: ' . $rcsOutput );
284 }
285 $file = $tmpfile;
286 $coCmd =~ s/-p%REVISION/-r%REVISION/;
287 }
288 my ( $text, $status, $stderr ) = Foswiki::Sandbox->sysCommand(
289 $coCmd,
290 REVISION => '1.' . $version,
291 FILENAME => $file
292 );
293
294 # The loaded version is reported on STDERR
295 my $isLatest = 0;
296 if ( defined $stderr
297 && $stderr =~ /revision 1\.(\d+)/s )
298 {
299 $isLatest = ( $version >= $1 );
300 }
301
302 # otherwise we will have to resort to numRevisions to tell if
303 # this is the latest rev, which is expensive. By returning false
304 # for isLatest we will force a reload upstairs if the latest rev
305 # is required.
306
307 if ($tmpfile) {
308 $text = Foswiki::Store::VC::Handler::readFile( $this, $tmpfile );
309 unlink Foswiki::Sandbox->untaintUnchecked($tmpfile);
310 unlink Foswiki::Sandbox->untaintUnchecked($tmpRevFile);
311 }
312
313 return ( $text, $isLatest );
314}
315
316# implements VC::Handler
317
# spent 92.8s (2.44ms+92.8) within Foswiki::Store::VC::RcsWrapHandler::getInfo which was called 21 times, avg 4.42s/call: # 21 times (2.44ms+92.8s) by Foswiki::Store::VC::Store::readTopic at line 116 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/VC/Store.pm, avg 4.42s/call
sub getInfo {
3181472.73ms my ( $this, $version ) = @_;
319
32021743µs if ( ( $this->noCheckinPending() )
# spent 743µs making 21 calls to Foswiki::Store::VC::Handler::noCheckinPending, avg 35µs/call
321 && ( !$version || $version > $this->_numRevisions() ) )
322 {
323 $version = $this->_numRevisions();
324 }
325 else {
3262122.7s $version = $this->_numRevisions() + 1
# spent 22.7s making 21 calls to Foswiki::Store::VC::RcsWrapHandler::_numRevisions, avg 1.08s/call
327 unless ( $version && $version <= $this->_numRevisions() );
328 }
3292147.6s my ( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
# spent 47.6s making 21 calls to Foswiki::Sandbox::sysCommand, avg 2.27s/call
330 $Foswiki::cfg{RCS}{infoCmd},
331 REVISION => '1.' . $version,
332 FILENAME => $this->{rcsFile}
333 );
334 if ( !$exit ) {
33521253µs if ( $rcsOut =~
# spent 253µs making 21 calls to Foswiki::Store::VC::RcsWrapHandler::CORE:match, avg 12µs/call
336 /^.*?date: ([^;]+); author: ([^;]*);[^\n]*\n([^\n]*)\n/s )
337 {
338 require Foswiki::Time;
339 my $info = {
340 version => $version,
341 date => Foswiki::Time::parseTime($1),
342 author => $2,
343 comment => $3,
344 };
345 if ( $rcsOut =~ /revision 1.([0-9]*)/ ) {
346 $info->{version} = $1;
347 }
348 return $info;
349 }
350 }
351
3522122.5s return $this->SUPER::getInfo($version);
# spent 22.5s making 21 calls to Foswiki::Store::VC::Handler::getInfo, avg 1.07s/call
353}
354
355# implements VC::Handler
356
# spent 46.6s (1.71ms+46.6) within Foswiki::Store::VC::RcsWrapHandler::_numRevisions which was called 33 times, avg 1.41s/call: # 21 times (764µs+22.7s) by Foswiki::Store::VC::RcsWrapHandler::getInfo at line 326, avg 1.08s/call # 7 times (591µs+22.5s) by Foswiki::Store::VC::Handler::getInfo at line 242 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/VC/Handler.pm, avg 3.21s/call # 5 times (354µs+1.41s) by Foswiki::Store::VC::Handler::getLatestRevisionID at line 449 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/VC/Handler.pm, avg 282ms/call
sub _numRevisions {
3571712.05ms my $this = shift;
358
35933137µs unless ( -e $this->{rcsFile} ) {
# spent 137µs making 33 calls to Foswiki::Store::VC::RcsWrapHandler::CORE:ftis, avg 4µs/call
360
361 # If there is no history, there can only be one.
3621556µs return 1 if -e $this->{file};
# spent 56µs making 15 calls to Foswiki::Store::VC::RcsWrapHandler::CORE:ftis, avg 4µs/call
363 return 0;
364 }
365
3661846.6s my ( $rcsOutput, $exit ) =
# spent 46.6s making 18 calls to Foswiki::Sandbox::sysCommand, avg 2.59s/call
367 Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{histCmd},
368 FILENAME => $this->{rcsFile} );
369 if ($exit) {
370 throw Error::Simple( 'RCS: '
371 . $Foswiki::cfg{RCS}{histCmd} . ' of '
372 . $this->hidePath( $this->{rcsFile} )
373 . ' failed: '
374 . $rcsOutput );
375 }
37618242µs if ( $rcsOutput =~ /head:\s+\d+\.(\d+)\n/ ) {
# spent 242µs making 18 calls to Foswiki::Store::VC::RcsWrapHandler::CORE:match, avg 13µs/call
377 return $1;
378 }
3791872µs if ( $rcsOutput =~ /total revisions: (\d+)\n/ ) {
# spent 72µs making 18 calls to Foswiki::Store::VC::RcsWrapHandler::CORE:match, avg 4µs/call
380 return $1;
381 }
382 return 1;
383}
384
385# implements VC::Handler
386# rev1 is the lower, rev2 is the higher revision
387sub revisionDiff {
388 my ( $this, $rev1, $rev2, $contextLines ) = @_;
389 my $tmp = '';
390 my $exit;
391 if ( $rev1 eq '1' && $rev2 eq '1' ) {
392 my $text = $this->getRevision(1);
393 $tmp = "1a1\n";
394 foreach ( split( /\r?\n/, $text ) ) {
395 $tmp = "$tmp> $_\n";
396 }
397 }
398 else {
399 $contextLines = 3 unless defined($contextLines);
400 ( $tmp, $exit ) = Foswiki::Sandbox->sysCommand(
401 $Foswiki::cfg{RCS}{diffCmd},
402 REVISION1 => '1.' . $rev1,
403 REVISION2 => '1.' . $rev2,
404 FILENAME => $this->{rcsFile},
405 CONTEXT => $contextLines
406 );
407
408 # comment out because we get a non-zero status for a good result!
409 #if( $exit ) {
410 # throw Error::Simple( 'RCS: '.$Foswiki::cfg{RCS}{diffCmd}.
411 # ' failed: '.$! );
412 #}
413 }
414
415 return parseRevisionDiff($tmp);
416}
417
418=begin TML
419
420---++ StaticMethod parseRevisionDiff( $text ) -> \@diffArray
421
422| Description: | parse the text into an array of diff cells |
423| #Description: | unlike Algorithm::Diff I concatinate lines of the same diffType that are sqential (this might be something that should be left up to the renderer) |
424| Parameter: =$text= | currently unified or rcsdiff format |
425| Return: =\@diffArray= | reference to an array of [ diffType, $right, $left ] |
426| TODO: | move into VC::Handler and add indirection in Store |
427
428=cut
429
430sub parseRevisionDiff {
431 my ($text) = @_;
432
433 my ($diffFormat) = 'normal'; #or rcs, unified...
434 my (@diffArray) = ();
435
436 $diffFormat = 'unified' if ( $text =~ /^---/s );
437
438 $text =~ s/\r//go; # cut CR
439
440 my $lineNumber = 1;
441 if ( $diffFormat eq 'unified' ) {
442 foreach ( split( /\r?\n/, $text ) ) {
443 if ( $lineNumber > 2 ) { #skip the first 2 lines (filenames)
444 if (/@@ [-+]([0-9]+)([,0-9]+)? [-+]([0-9]+)(,[0-9]+)? @@/) {
445
446 #line number
447 push @diffArray, [ 'l', $1, $3 ];
448 }
449 elsif (/^\-(.*)$/) {
450 push @diffArray, [ '-', $1, '' ];
451 }
452 elsif (/^\+(.*)$/) {
453 push @diffArray, [ '+', '', $1 ];
454 }
455 else {
456 s/^ (.*)$/$1/go;
457 push @diffArray, [ 'u', $_, $_ ];
458 }
459 }
460 $lineNumber++;
461 }
462 }
463 else {
464
465 #'normal' rcsdiff output
466 foreach ( split( /\r?\n/, $text ) ) {
467 if (/^([0-9]+)[0-9\,]*([acd])([0-9]+)/) {
468
469 #line number
470 push @diffArray, [ 'l', $1, $3 ];
471 }
472 elsif (/^< (.*)$/) {
473 push @diffArray, [ '-', $1, '' ];
474 }
475 elsif (/^> (.*)$/) {
476 push @diffArray, [ '+', '', $1 ];
477 }
478 else {
479
480 #push @diffArray, ['u', '', ''];
481 }
482 }
483 }
484 return \@diffArray;
485}
486
487sub _lock {
488 my $this = shift;
489
490 return unless -e $this->{rcsFile};
491
492 # Try and get a lock on the file
493 my ( $rcsOutput, $exit ) =
494 Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{lockCmd},
495 FILENAME => $this->{file} );
496
497 if ($exit) {
498
499 # if the lock has been set more than 24h ago, let's try to break it
500 # and then retry. Should not happen unless in Cairo upgrade
501 # scenarios - see Item2102
502 if ( ( time - ( stat( $this->{rcsFile} ) )[9] ) > 3600 ) {
503 warn 'Automatic recovery: breaking lock for ' . $this->{file};
504 Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{breaklockCmd},
505 FILENAME => $this->{file} );
506 ( $rcsOutput, $exit ) =
507 Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{lockCmd},
508 FILENAME => $this->{file} );
509 }
510 if ($exit) {
511
512 # still no luck - bailing out
513 $rcsOutput ||= '';
514 throw Error::Simple( 'RCS: '
515 . $Foswiki::cfg{RCS}{lockCmd}
516 . ' failed: '
517 . $rcsOutput );
518 }
519 }
520 chmod( $Foswiki::cfg{RCS}{filePermission}, $this->{file} );
521}
522
523# implements VC::Handler
524sub getRevisionAtTime {
525 my ( $this, $date ) = @_;
526
527 unless ( -e $this->{rcsFile} ) {
528 return ( $date >= ( stat( $this->{file} ) )[9] ) ? 1 : undef;
529 }
530
531 require Foswiki::Time;
532 my $sdate = Foswiki::Time::formatTime( $date, '$rcs', 'gmtime' );
533 my ( $rcsOutput, $exit ) = Foswiki::Sandbox->sysCommand(
534 $Foswiki::cfg{RCS}{rlogDateCmd},
535 DATE => $sdate,
536 FILENAME => $this->{file}
537 );
538
539 my $version = undef;
540 if ( $rcsOutput =~ m/revision \d+\.(\d+)/ ) {
541 $version = $1;
542 }
543
544 if ( $version && !$this->noCheckinPending() ) {
545
546 # Check the file date
547 $version++ if ( $date >= ( stat( $this->{file} ) )[9] );
548 }
549 return $version;
550}
551
55216µs1;
553__END__
 
# spent 193µs within Foswiki::Store::VC::RcsWrapHandler::CORE:ftis which was called 48 times, avg 4µs/call: # 33 times (137µs+0s) by Foswiki::Store::VC::RcsWrapHandler::_numRevisions at line 359, avg 4µs/call # 15 times (56µs+0s) by Foswiki::Store::VC::RcsWrapHandler::_numRevisions at line 362, avg 4µs/call
sub Foswiki::Store::VC::RcsWrapHandler::CORE:ftis; # opcode
# spent 568µs within Foswiki::Store::VC::RcsWrapHandler::CORE:match which was called 57 times, avg 10µs/call: # 21 times (253µs+0s) by Foswiki::Store::VC::RcsWrapHandler::getInfo at line 335, avg 12µs/call # 18 times (242µs+0s) by Foswiki::Store::VC::RcsWrapHandler::_numRevisions at line 376, avg 13µs/call # 18 times (72µs+0s) by Foswiki::Store::VC::RcsWrapHandler::_numRevisions at line 379, avg 4µs/call
sub Foswiki::Store::VC::RcsWrapHandler::CORE:match; # opcode