# directive always appears *outside* of an <container>.
my $before = ($content =~ m|^(.*\n)#?\s*LoadModule\s+[^\n]+\n|s)[0];
+
+ # the '()=' trick forces list context and the scalar
+ # assignment counts the number of list members (aka number
+ # of matches) then
my $cntopen = () = ($before =~ m|^\s*<[^/].*$|mg);
my $cntclose = () = ($before =~ m|^\s*</.*$|mg);
else {
# put our cmd after the section containing the last
# LoadModule.
- $content =~ s!\A((?:(?:^\s*(?:[^<]|<[^/]).*(?:$)\n)*^\s*</.*(?:$)\n?){$cntopen})!$1$c$lmd\n!m;
+ my $found =
+ $content =~ s!\A ( # string and capture start
+ (?:(?:
+ ^\s* # start of conf line with a
+ (?:[^<]|<[^/]) # directive which does not
+ # start with '</'
+
+ .*(?:$)\n # rest of the line.
+ # the '$' is in parentheses
+ # to avoid misinterpreting
+ # the string "$\" as
+ # perl variable.
+
+ )* # catch as much as possible
+ # of such lines. (including
+ # zero)
+
+ ^\s*</.*(?:$)\n? # after the above, we
+ # expect a config line with
+ # a closing container (</)
+
+ ) {$cntopen} # the whole pattern (bunch
+ # of lines that end up with
+ # a closing directive) must
+ # be repeated $cntopen
+ # times. That's it.
+ # Simple, eh? ;-)
+
+ ) # capture end
+ !$1$c$lmd\n!mx;
+
+ unless ($found) {
+ error('Configuration file is not valid. There are '
+ . 'sections opened and not closed.');
+ exit(1);
+ }
}
} else {
# replace already existing LoadModule line