my ($MarkBegin, $MarkEnd, $Trailer, $ParamBegin, $ParamEnd, $Placement,
$Package, $File, $Block, $Multi, $InsertRemove, $Comment, $CommentEnd,
$MatchLine, $RegexpMatch, $StdinContent, $NewContent, $InPlace,
- $NoClose, $FileHandle, @Lines);
+ $NoClose, $FileHandle, @Lines, $LinesCount);
# Placement modes
use constant APPEND_AT_END => 0;
# --------------
sub do_it {
- slurp();
+ $LinesCount = slurp();
if (DO_CHANGE == $InsertRemove) {
$StdinContent = &stdin_content;
change() or add();
# If FILE does not have a trailing newline, be sure to add it
# before appending anything else.
-
if (@Lines and $Lines[$#Lines] !~ m/\n$/s) {
$Lines[$#Lines] .= "\n";
}
+
+ return scalar @Lines;
}
sub add() {
push(@Lines, $StdinContent);
}
}
- return scalar(@Lines); # whatever
+ # add the number of lines in added content to safety counter
+ $LinesCount += ($StdinContent =~ tr/\n//);
+ return $LinesCount; # whatever true
}
sub del() {
my (@filtered);
foreach (@Lines) {
- push (@filtered, $_)
- unless (/^$mybegin(?:$mytrailer)?$/o .. /^$myend(?:$mytrailer)?$/o);
-
+ if (/^$mybegin(?:$mytrailer)?$/o .. /^$myend(?:$mytrailer)?$/o) {
+ # additional safety counter for double-check
+ -- $LinesCount;
+ } else {
+ push (@filtered, $_);
+ }
# for safety check:
$bm_found = 1 if (/^$mybegin(?:$mytrailer)?$/o);
$em_found = 1 if (/^$myend(?:$mytrailer)?$/o);
# safety exit
die "$ProgramName: no end-mark after begin-mark!\n";
}
- return scalar(@Lines); # whatever
+ return $LinesCount; # whatever
}
sub change() {
$skip = 0; # skip original block
foreach (@Lines) {
if (! $done and $skip > 0) {
+ -- $LinesCount;
if (/^$myend(?:$mytrailer)?$/o) {
++ $done; # skipped all that was to skip
} else {
}
elsif (0 == $skip and $_ =~ /^$mybegin(?:$mytrailer)?$/o) {
push (@filtered, $StdinContent);
+ $LinesCount += ($StdinContent =~ tr/\n//);
$skip = 1;
}
else {
# put it all thogether
my $newContent = join('', @Lines);
- unless (length($newContent)) {
+ unless (length($newContent) or 0 == $LinesCount) {
# safety exit in last second :)
die "$ProgramName: New content empty -- aborting file alteration!\n";
}
sysseek(*$FileHandle, 0, SEEK_SET)
or die "$ProgramName: Failed to seek to the begining of file ($!)\n";
}
- my $wb = syswrite($FileHandle, $newContent);
- if (! $wb or length($newContent) != $wb) {
- # FIXME: try restoring backup copy
- die "$ProgramName: Failed to write the content to '$File' ($!)\n";
+ if (length($newContent)) {
+ my $wb = syswrite($FileHandle, $newContent);
+ if (! $wb or length($newContent) != $wb) {
+ # FIXME: try restoring backup copy
+ my $ncl = length($newContent);
+ die "$ProgramName: Failed to write the content to '$File' (wb=$wb, len=$ncl, err:$!)\n";
+ }
}
if ($NoClose) {
# this could be handy for files that had stuff appended
# write content in new file in single write op
sysopen ($FileHandle, $file_new, O_CREAT|O_TRUNC|O_WRONLY)
or die "$ProgramName: Failed to open file '$File' for writing ($!)\n";
- my $wb = syswrite($FileHandle, $newContent);
- if (! $wb or length($newContent) != $wb) {
- unlink($file_new);
- die "$ProgramName: Failed to write the content to '$File' ($!)\n";
+ if (length($newContent)) {
+ my $wb = syswrite($FileHandle, $newContent);
+ if (! $wb or length($newContent) != $wb) {
+ unlink($file_new);
+ my ($ncl) = length($newContent);
+ die "$ProgramName: Failed to write the content to '$File' (wb=$wb, len=$ncl, err:$!)\n";
+ }
}
close($FileHandle);
# do the moving (should be atomic)