## Copyright (C) 1998 Hrvoje Niksic
## Modification by Zeljko Boros (block entries, removing old entries)
## More options and use strict by Zoran Dzelajlija on 2004-02-24
+## Quite a few improvements by Damir Dzeko on 2005-03-18 (see bellow)
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## -> reformated code, introduced coding conventions
## -> increased reliability through atomic actualization
## -> everything is done in the memory - more mem, less i/o
-## -> removed append mode - in-place editing considered harmfull
+## -> removed append mode - in-place editing considered harmful
## -> added in-place mode as option
use strict;
-r | --remove Remove entry PACKAGE from FILE.
Default is to add lines from stdin.
+ -x | --change Modify existing block, or add it if
+ it does not exist but the begin mark
+ can be found.
+
-m | --allow-multiple Allow multiple blocks of the same type.
By default, old blocks are replaced with
the new one.
-h | --help Print this message (usage reference).
-
+
--version Print version message.
- Placement control:
# InsertRemove modes
use constant DO_REMOVE => 0;
use constant DO_INSERT => 1;
+use constant DO_CHANGE => 2;
# Operation defaults
$InsertRemove = DO_INSERT;
elsif (/^-r$/ || /^--remove$/) {
$InsertRemove = DO_REMOVE;
}
+ elsif (/^-x$/ || /^--change$/) {
+ $InsertRemove = DO_CHANGE;
+ }
elsif (/^-m$/ || /^--allow-multi(?:ple)?$/) {
$Multi = 1;
}
unshift(@ARGV, $_);
last;
}
+
+ if ($Multi and DO_CHANGE == $InsertRemove) {
+ die "$ProgramName: Cannot use both `--change' and `--allow-multiple'\n";
+ }
}
$Package = shift or die $UsageShort;
sub do_it {
slurp();
- if (DO_INSERT == $InsertRemove) {
+ if (DO_CHANGE == $InsertRemove) {
+ $StdinContent = &stdin_content;
+ change() or add();
+ }
+ elsif (DO_INSERT == $InsertRemove) {
$StdinContent = &stdin_content;
del() unless $Multi;
add();
return scalar(@Lines); # whatever
}
+sub change() {
+ my ($mytrailer, $mybegin, $myend) =
+ ($Trailer, $MarkBegin, $MarkEnd);
+
+ my ($bm_found, $em_found); # begin/end mark found indicator
+
+ # Make the strings regexp-friendly by quoting non-word chars.
+ $mybegin =~ s/\W/\\$&/g;
+ $myend =~ s/\W/\\$&/g;
+ $mytrailer =~ s/\W/\\$&/g;
+
+ my (@filtered, $done, $skip);
+ $done = 0; # job done once
+ $skip = 0; # skip original block
+ foreach (@Lines) {
+ if (! $done and $skip > 0) {
+ if (/^$myend(?:$mytrailer)?$/o) {
+ ++ $done; # skipped all that was to skip
+ } else {
+ ++ $skip; # count lines being skipped
+ }
+ }
+ elsif (0 == $skip and $_ =~ /^$mybegin(?:$mytrailer)?$/o) {
+ push (@filtered, $StdinContent);
+ $skip = 1;
+ }
+ else {
+ push (@filtered, $_)
+ }
+ # for safety check:
+ $bm_found = 1 if (/^$mybegin(?:$mytrailer)?$/o);
+ $em_found = 1 if (/^$myend(?:$mytrailer)?$/o);
+ }
+ if ($bm_found and $em_found) {
+ -- $skip; # correct the counter
+ DEBUG and print STDERR "Replaced block of $skip lines\n";
+ @Lines = @filtered;
+ }
+ elsif ($bm_found and ! $em_found) {
+ # safety exit
+ die "$ProgramName: no end-mark after begin-mark!\n";
+ }
+ return $done;
+}
+
# written by ddzeko@srce.hr, 2005-03-18
# to improve reliabilitah :)
#
# path to cp-update script
CPUPDATE=../cp-update
-tests: test0 test1 test2 test3 test4 test5 test6
+tests: test0 test1 test2 test3 test4 test5 test6 test7 test8
@echo "All tests completed successfully"
@cp test-file.start test-file
clean: test0 test-file.start
- rm -f test[0-9] test[0-9][0-9] test-file.[0-9]*
+ rm -f test[0-9] test[0-9][a-zA-Z0-9] test-file.[0-9]*
# prepare everything for test sequence
test0: test-file.start
mv test-new $@
echo Succeeded $@
+# change/replace existing blocks
+# - even if they do not previously exist (fall-back to insert)
+test6:
+ perl -e 'print "test line $$_ by $$ARGV[0]\n" for 14..18;' testChange \
+ | $(CPUPDATE) -x -i 'something' testChange test-file
+ cp test-file test-new
+ cmp test-new $@.ok
+ mv test-new $@
+ echo Succeeded $@
+
+# change/replace existing blocks
+# - just change it Sam
+test7: test6
+ cp test6 test6c
+ perl -e 'print "test line $$_ by $$ARGV[0]\n" for 22..26;' testChange \
+ | $(CPUPDATE) -x -i 'something' testChange test6c
+ cp test6c test-new
+ cmp test-new $@.ok
+ mv test-new $@
+ echo Succeeded $@
+
# now remove everything
-test6: test1 test2 test3 test4 test5
- for i in test[1-4]; do $(CPUPDATE) -r $$i test-file; done
+test8: test1 test2 test3 test4 test5 test6
+ for i in test[1-4] testChange; do $(CPUPDATE) -r $$i test-file; done
$(CPUPDATE) -r -c ';' test5 test-file
cp test-file.start $@.ok
echo >> $@.ok
This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
so they can check is everything ok with the script. Empty line:
# Here we have a piece that looks like a comment
# Begin update by CARNet package broken2
It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
Block inserted by test2
# End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
so they can check is everything ok with the script. Empty line:
# Here we have a piece that looks like a comment
# Begin update by CARNet package broken2
It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
Block inserted by test2
# End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
so they can check is everything ok with the script. Empty line:
# Here we have a piece that looks like a comment
# Begin update by CARNet package broken2
It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
Block inserted by test2
# End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
so they can check is everything ok with the script. Empty line:
# Here we have a piece that looks like a comment
# Begin update by CARNet package broken2
It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
# Begin update by CARNet package test4 -- DO NOT DELETE THIS LINE!
Block inserted by test4
# End update by CARNet package test4 -- DO NOT DELETE THIS LINE!
Block inserted by test2
# End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
so they can check is everything ok with the script. Empty line:
# Here we have a piece that looks like a comment
# Begin update by CARNet package broken2
It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
# Begin update by CARNet package test4 -- DO NOT DELETE THIS LINE!
Block inserted by test4
# End update by CARNet package test4 -- DO NOT DELETE THIS LINE!
+# Begin update by CARNet package test2 -- DO NOT DELETE THIS LINE!
+Block inserted by test2
+# End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
so they can check is everything ok with the script. Empty line:
# Here we have a piece that looks like a comment
[samba]
brasil = de Janeiro
+; Begin update by CARNet package test5 -- DO NOT DELETE THIS LINE!
+test line 1 by test5
+test line 2 by test5
+test line 3 by test5
+test line 4 by test5
+test line 5 by test5
+; End update by CARNet package test5 -- DO NOT DELETE THIS LINE!
<apache>
mohican = the last
</apache>
+# Begin update by CARNet package test3 -- DO NOT DELETE THIS LINE!
+Block inserted by test3
+# End update by CARNet package test3 -- DO NOT DELETE THIS LINE!
options {
something +more;
+# Begin update by CARNet package testChange -- DO NOT DELETE THIS LINE!
+test line 14 by testChange
+test line 15 by testChange
+test line 16 by testChange
+test line 17 by testChange
+test line 18 by testChange
+# End update by CARNet package testChange -- DO NOT DELETE THIS LINE!
}
# update this
# Begin update by CARNet package broken2
It's the end of the file and guess what? This line does not end with \n
+# Begin update by CARNet package test4 -- DO NOT DELETE THIS LINE!
+Block inserted by test4
+# End update by CARNet package test4 -- DO NOT DELETE THIS LINE!
--- /dev/null
+# Begin update by CARNet package test2 -- DO NOT DELETE THIS LINE!
+Block inserted by test2
+# End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
+This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+so they can check is everything ok with the script. Empty line:
+
+# Here we have a piece that looks like a comment
+; following line says that you should not delete it:
+ -- DO NOT DELETE THIS LINE!
+
+[samba]
+ brasil = de Janeiro
+; Begin update by CARNet package test5 -- DO NOT DELETE THIS LINE!
+test line 1 by test5
+test line 2 by test5
+test line 3 by test5
+test line 4 by test5
+test line 5 by test5
+; End update by CARNet package test5 -- DO NOT DELETE THIS LINE!
+
+<apache>
+ mohican = the last
+</apache>
+# Begin update by CARNet package test3 -- DO NOT DELETE THIS LINE!
+Block inserted by test3
+# End update by CARNet package test3 -- DO NOT DELETE THIS LINE!
+
+options {
+ something +more;
+# Begin update by CARNet package testChange -- DO NOT DELETE THIS LINE!
+test line 22 by testChange
+test line 23 by testChange
+test line 24 by testChange
+test line 25 by testChange
+test line 26 by testChange
+# End update by CARNet package testChange -- DO NOT DELETE THIS LINE!
+}
+
+# update this
+
+# Begin update by CARNet package broken
+this is for compatibility with older version which did not add
+ -- DO NOT DELETE THIS LINE!
+string after the package name
+# End update by CARNet package broken
+
+# Begin update by CARNet package broken2
+
+It's the end of the file and guess what? This line does not end with \n
+# Begin update by CARNet package test4 -- DO NOT DELETE THIS LINE!
+Block inserted by test4
+# End update by CARNet package test4 -- DO NOT DELETE THIS LINE!
--- /dev/null
+This is the top of the test file for cp-update maintenance team
+so they can check is everything ok with the script. Empty line:
+
+# Here we have a piece that looks like a comment
+; following line says that you should not delete it:
+ -- DO NOT DELETE THIS LINE!
+
+[samba]
+ brasil = de Janeiro
+
+<apache>
+ mohican = the last
+</apache>
+
+options {
+ something +more;
+}
+
+# update this
+
+# Begin update by CARNet package broken
+this is for compatibility with older version which did not add
+ -- DO NOT DELETE THIS LINE!
+string after the package name
+# End update by CARNet package broken
+
+# Begin update by CARNet package broken2
+
+It's the end of the file and guess what? This line does not end with \n