--- Begin Message ---
Package: dpkg
Version: 1.6.13
Severity: wishlist
The following script and patch should be applied while standing in
the "scripts" subdirectory of the `dpkg' sources.
This allows `control' to contain a variable expansion in the
"Package:" field, like "Package: guile${GUILE_SHORTVERSION}", where
GUILE_SHORTVERSION is defined in a substvars file. I have updated
the manual also, this behaviour and how to use it some are explained
there.
For my version of the `guile' packages, what I'm doing is using the
upstream "GUILE-VERSION" includer from "debian/rules", with GNU
Make's "include" instruction, and then also using it as the base for
a substvars file. When I (or debhelper) call any of the `dpkg-*'
scripts that needs to know what package to act on (via the -p<pkg>
option), the real name of the package is given, by way of a Make
macro expansion that amounts to the same expansion the substvars on
the "Package:" field will do, so they match:
foopkg = foo${FOO_SHORTVERSION}
sometarget:
dh_dosomething --package=${foopkg}
${foopkg}.postinst: foo.postinst.in
dpkg-substvars -p${foopkg} < $< > $@
This avoids hard-coding package names like "guile1.4", or "libguile9"
in "debian/control", thus improving maintainability. There are other
Debian packages out there that could benefit from this backwards
compatible (afaict) modification. Please see the "debian/rules" from
my version of the Guile "debian/*" scripts for a more complex
example, if you've time and curiosity.
Included is `dpkg-substvars', which reads stdin, performs variable
substitutions, and writes to stdout. It is derived directly from
`dpkg-gencontrol'. You can give it the `-@' option to have it
replace variables enclosed in "@varname@", rather than the usual
"${varname}", so that it can work on shell scripts and makefile
includers.
It is very useful for generating maintainer scripts that have version
numbers, etc. inside of them, yet again, avoiding a possibly missed
edit on upstream version upgrade, and thus improving package
maintainability.
My version of the Guile debian/* scripts may be viewed via
<URL:http://bittersweet.inetarena.com/cgi-bin/viewcvs.cgi/guile-core/debian>
... if you are curious. I plan to share them with the real Guile
package maintainer, but cannot do so until after the attached changes
are part of the distributed `dpkg'.
dpkg-substvars
Description: Binary data
--- dpkg-source.1 2000/06/27 05:42:50 1.1
+++ dpkg-source.1 2000/06/27 07:34:13
@@ -2,9 +2,9 @@
.\" Authors: Ian Jackson
.TH DPKG\-SOURCE 1 "7th August" "Debian Project" "Debian GNU/Linux manual"
.SH NAME
-dpkg\-source, dpkg\-gencontrol, dpkg\-shlibdeps, dpkg\-genchanges,
-dpkg\-buildpackage, dpkg\-distaddfile, dpkg\-parsechangelog
-\- Debian source package tools
+dpkg\-source, dpkg\-gencontrol, dpkg\-substvars, dpkg\-shlibdeps,
+dpkg\-genchanges, dpkg\-buildpackage, dpkg\-distaddfile,
+dpkg\-parsechangelog \- Debian source package tools
.SH SYNOPSIS
.B dpkg-source
.BI "-x " filename .dsc
@@ -15,6 +15,9 @@
.B dpkg-gencontrol
.RI [ options ]
.br
+.B dpkg-substvars
+.RI [ options ]
+.br
.B dpkg-shlibdeps
.IR options
.br
@@ -39,6 +42,13 @@
for the binary package to
.BR debian/files .
+.B dpkg-substvars
+parses
+.B debian/substvars
+then reads an input file, performs variable substitution on it, and
+writes the result back out. See below for a discussion of output
+substitution.
+
.B dpkg-shlibdeps
calculates shared library dependencies for executables named in its
arguments. The dependencies are added to the substitution
@@ -148,7 +158,7 @@
.BI -V name = value
Set an output substitution variable.
This option is understood by
-.BR dpkg-source ", " dpkg-gencontrol " and " dpkg-genchanges .
+.BR dpkg-source ", " dpkg-gencontrol ", " dpkg-substvars " and "
dpkg-genchanges .
See below for a discussion of output substitution.
.TP
.BI -T substvarsfile
@@ -159,17 +169,17 @@
the default is
.BR debian/substvars .
This option is understood by
-.BR dpkg-source ", " dpkg-gencontrol ", " dpkg-shlibdeps " and "
dpkg-genchanges .
+.BR dpkg-source ", " dpkg-gencontrol ", " dpkg-substvars ", " dpkg-shlibdeps "
and " dpkg-genchanges .
.TP
.BI -D field = value
Override or add an output control file field.
This option is understood by
-.BR dpkg-source ", " dpkg-gencontrol " and " dpkg-genchanges .
+.BR dpkg-source ", " dpkg-gencontrol ", " dpkg-substvars " and "
dpkg-genchanges .
.TP
.BI -U field
Remove an output control file field.
This option is understood by
-.BR dpkg-source ", " dpkg-gencontrol " and " dpkg-genchanges .
+.BR dpkg-source ", " dpkg-gencontrol ", " dpkg-substvars " and "
dpkg-genchanges .
.TP
.BR -b | -B
For
@@ -200,14 +210,14 @@
default is
.BR debian/control .
This option is understood by
-.BR dpkg-source ", " dpkg-gencontrol " and " dpkg-genchanges .
+.BR dpkg-source ", " dpkg-gencontrol ", " dpkg-substvars " and "
dpkg-genchanges .
.TP
.BI -l changelogfile
Specifies the change log file to read information from. The
default is
.BR debian/changelog .
This option is understood by
-.BR dpkg-source ", " dpkg-gencontrol " and " dpkg-genchanges .
+.BR dpkg-source ", " dpkg-gencontrol ", " dpkg-substvars " and "
dpkg-genchanges .
.TP
.BI -f fileslistfile
Read or write the list of files to be uploaded here, rather than using
@@ -223,7 +233,7 @@
the standard format described in the
.IR "Debian packaging manual" .
This option is understood by
-.BR dpkg-source ", " dpkg-gencontrol " and " dpkg-genchanges .
+.BR dpkg-source ", " dpkg-gencontrol ", " dpkg-substvars " and "
dpkg-genchanges .
.SH DPKG-SOURCE OPTIONS
When the common options
.BR -c " and " -l
@@ -409,7 +419,7 @@
.TP
.BI -P packagebuilddir
Tells
-.B dpkg-source
+.B dpkg-gencontrol
that the package is being built in
.I packagebuilddir
instead of
@@ -429,6 +439,27 @@
if
.B -P
was used).
+.SH DPKG-SUBSTVARS OPTIONS
+.B dpkg-substvars
+does not take any non-option arguments.
+.TP
+.BI -i infile
+Read input from
+.IR infile .
+By default, it reads from standard input.
+.TP
+.BI -o outfile
+Write output to
+.IR outfile .
+By default, it writes to standard output, with warnings about
+undefined variables being printed to standard error.
+.TP
+.BI -p package
+Generate information for the binary package
+.IR package .
+If the source control file lists only one binary package then this
+option may be omitted; otherwise it is essential to select which
+binary package's information to generate.
.SH DPKG-SHLIBDEPS OPTIONS
.B dpkg-shlibdeps
interprets non-option arguments as executable names, just as if they'd
@@ -488,7 +519,7 @@
.RB ( debian/substvars
by default).
.SH DPKG-GENCHANGES OPTIONS
-.B dpkg-gencontrol
+.B dpkg-genchanges
does not take any non-option arguments.
.TP
.BI -u uploadfilesdir
@@ -580,8 +611,7 @@
.TP
.B -i[<regexp>]
Passed unchanged to
-.B dpkg-source
-.TP
+.BR dpkg-source .
.SH DPKG-DISTADDFILE ARGUMENTS
.B dpkg-distaddfile
does not take any non-common options. It takes three non-option
@@ -601,28 +631,77 @@
does not take any non-common options or non-option arguments.
.SH VARIABLE SUBSTITUTION
Before
-.BR dpkg-source ", " dpkg-gencontrol " and " dpkg-genchanges
+.BR dpkg-source ", " dpkg-gencontrol ", " dpkg-substvars " and "
dpkg-genchanges
write their control information (to the source control file
.B .dsc
for
.B dpkg-source
and to standard output for
-.BR dpkg-gencontrol " and " dpkg-genchanges )
+.BR dpkg-gencontrol ", " dpkg-substvars " and " dpkg-genchanges )
they perform some variable substitutions on the output file.
A variable substitution has the form
.BI ${ variable-name }\fR.
-Variable names consist of alphanumerics, hyphens and colons and start
-with an alphanumeric. Variable substitutions are performed repeatedly
-until none are left; the full text of the field after the substitution
-is rescanned to look for more substitutions.
+Variable names consist of alphanumerics, underscores, hyphens and
+colons, and start with an alphanumeric. Variable substitutions are
+performed repeatedly until none are left; the full text of the field
+after the substitution is rescanned to look for more substitutions.
+
+The
+.B Package
+field of
+.B debian/control
+is also transformed, so it is possible, for example, to add a major
+version number to the name of a package, by saying something like:
+.B Package: foo${FOO_MAJOR_VERSION}
+in
+.BR debian/control ,
+and then, in
+.BR debian/substvars ", define " FOO_MAJOR_VERSION=3 .
+When you do this, use the
+.B -p
+switch, like
+.BI -p foo3\fR,
+perhaps by using a macro expansion from a makefile to fill in the
+variable part (the 3 in this example) of the \fB-p\fR option's
+argument.
+
+For the most part, the syntax of the
+.B debian/substvars
+file is compatible with GNU Make, so you can use the
+.B include
+instruction in your
+.B debian/rules
+to bring in the
+.B debian/substvars
+values if you like. Note that
+.B dpkg-shlibdeps
+will generate entries that are \fBnot\fR compatible with Make. A good
+workaround is to include a substvars file by a different name, then
+use it as a base for the actual \fBdebian/substvars\fR (which you
+generate) to be used by the \fBdpkg-*\fR scripts. That is a good time
+to add values to the \fBdebian/substvars\fR that have been computed by
+your \fBdebian/rules\fR.
+
+If
+.B dpkg-substvars
+is given the
+.B -@
+switch, a variable substitution will have the form
+.BI @ variable-name @
+so that substitutions can be made in shell scripts or makefiles
+without disturbing normal shell or make variables in them. The
+.B debian/substvars
+file maintains the same syntax as before though, with dollar signs and
+curly braces, not `at' signs.
-After all the substitutions have been done each occurence of the
+For all of these utilities except for
+.BR dpkg-substvars ,
+after all the substitutions have been done, each occurence of the
string
.B ${}
-(which is not a legal substitution) is replaced with a
-.B $
-sign.
+is replaced with
+.BR $ .
Variables can be set using the
.B -V
@@ -653,7 +732,8 @@
.B dpkg-gencontrol
will use
.B du -k debian/tmp
-to find the default value.
+to find the default value. This variable is \fBnot\fR defined by
+.BR dpkg-substvars .
.TP
.B Extra-Size
Additional disk space used when the package is installed. If this
@@ -662,7 +742,8 @@
variable (whether set explicitly or using the default value) before it
is copied into the
.B Installed-Size
-control file field.
+control file field. This variable is not defined for
+.BR dpkg-substvars .
.TP
.BI F: fieldname
The value of the output field
--- controllib.pl 2000/06/25 10:16:25 1.1
+++ controllib.pl 2000/06/25 21:45:40
@@ -76,11 +76,56 @@
$substvar{'Arch'}= $arch;
}
+sub parsevarlistfile {
+ if (length($varlistfile)) {
+ $varlistfile="./$varlistfile" if $varlistfile =~ m/\s/;
+ if (open(SV,"< $varlistfile")) {
+ while (<SV>) {
+ next if m/^\#/ || !m/\S/;
+ s/\s*\n$//;
+ m/^(\w[-_:0-9A-Za-z]*)\=/ ||
+ &error("bad line in substvars file $varlistfile at line
$.");
+ $substvar{$1}= $';
+ }
+ close(SV);
+ } elsif ($! != ENOENT ) {
+ &error("unable to open substvars file $varlistfile: $!");
+ }
+ }
+}
+
+# This must be done when -@ is given otherwise if, for instance,
+# substvars contains:
+# BLAH=a
+# FOO=b
+# VAR=${BLAH}.${FOO}
+# ... a maint script contains:
+# @VAR@
+# ... and it would expand to:
+# ${BLAH}.${FOO}
+# ... rather than to
+# a.b
+# ... without calling &expandsubstvars; first.
+# See: dpkg-substvars for an example of where this is used.
+sub expandsubstvars {
+ for $f (keys %f) { $substvar{"F:$f"}= $f{$f}; }
+ for $sv (keys %substvar) {
+ $substvar{$sv} = &substvars($substvar{$sv});
+ }
+}
+
sub substvars {
- my ($v) = @_;
- my ($lhs,$vn,$rhs,$count);
+ my ($v,$at) = @_;
+ my ($lhs,$vn,$rhs,$count,$re);
$count=0;
- while ($v =~ m/\$\{([-:0-9a-z]+)\}/i) {
+ $re = "([-_:0-9a-z]+)";
+ if ($at) {
+ $re = '\@'.$re.'\@';
+ }
+ else {
+ $re = '\$\{'.$re.'\}';
+ }
+ while ($v =~ m/$re/i) {
$count < $maxsubsts ||
&error("too many substitutions - recursive ? - in \`$v'");
$lhs=$`; $vn=$1; $rhs=$';
@@ -97,22 +142,7 @@
sub outputclose {
my ($dosubstvars) = @_;
- for $f (keys %f) { $substvar{"F:$f"}= $f{$f}; }
- if (length($varlistfile) and $dosubstvars) {
- $varlistfile="./$varlistfile" if $varlistfile =~ m/\s/;
- if (open(SV,"< $varlistfile")) {
- while (<SV>) {
- next if m/^\#/ || !m/\S/;
- s/\s*\n$//;
- m/^(\w[-:0-9A-Za-z]*)\=/ ||
- &error("bad line in substvars file $varlistfile at line
$.");
- $substvar{$1}= $';
- }
- close(SV);
- } elsif ($! != ENOENT ) {
- &error("unable to open substvars file $varlistfile: $!");
- }
- }
+ &parsevarlistfile if $dosubstvars;
for $f (sort { $fieldimps{$b} <=> $fieldimps{$a} } keys %f) {
$v= $f{$f};
if ($dosubstvars) {
8$1; $v=$2;
$cf= &capit($cf);
$fi{"$source$index $cf"}= $v;
- if (lc $cf eq 'package') { $p2i{"$source $v"}= $index; }
+ if (lc $cf eq 'package') {
+ $v = &substvars($v);
+ $p2i{"$source $v"}= $index;
+ }
} elsif (m/^\s+\S/) {
length($cf) || &syntax("continued value line not in field");
$fi{"$source$index $cf"}.= "\n$_";
--- dpkg-genchanges.pl 2000/06/25 10:27:18 1.1
+++ dpkg-genchanges.pl 2000/06/25 10:51:21
@@ -97,6 +97,7 @@
&findarch;
&parsechangelog;
+&parsevarlistfile;
&parsecontrolfile;
$fileslistfile="./$fileslistfile" if $fileslistfile =~ m/^\s/;
8('general section of control info file'); }
} elsif (s/^C(\d+) //) {
#print STDERR "P key >$_< value >$v<\n";
- $i=$1; $p=$fi{"C$i Package"}; $a=$fi{"C$i Architecture"};
+ $i=$1; $p=&substvars($fi{"C$i Package"}); $a=$fi{"C$i Architecture"};
if (!defined($p2f{$p})) {
if ($a eq 'any' || ($a eq 'all' && !$archspecific) ||
grep($_ eq $substvar{'Arch'}, split(/\s+/, $a))) {
--- dpkg-gencontrol.pl 2000/06/25 10:19:07 1.1
+++ dpkg-gencontrol.pl 2000/06/25 10:26:54
@@ -91,8 +91,9 @@
&findarch;
&parsechangelog;
+&parsevarlistfile;
&parsecontrolfile;
-
+
if (length($oppackage)) {
defined($p2i{"C $oppackage"}) || &error("package $oppackage not in control
info");
$myindex= $p2i{"C $oppackage"};
@@ -101,6 +102,7 @@
@packages==1 ||
&error("must specify package since control info has many (@packages)");
$myindex=1;
+ $oppackage= &substvars($f{'Package'});
}
#print STDERR "myindex $myindex\n";
@@ -117,7 +119,9 @@
else { &unknown('general section of control info file'); }
} elsif (s/^C$myindex //) {
#print STDERR "P key >$_< value >$v<\n";
- if (m/^(Package|Description|Essential|Pre-Depends|Depends)$/ ||
+ if (m/^Package$/) {
+ $f{&substvars($_)}= $v;
+ } elsif (m/^(Description|Essential|Pre-Depends|Depends)$/ ||
m/^(Recommends|Suggests|Enhances|Optional|Conflicts|Provides|Replaces)$/) {
$f{$_}= $v;
} elsif (m/^Section$|^Priority$/) {
@@ -161,6 +165,8 @@
$f{'Version'}= $forceversion if length($forceversion);
+for $f (keys %f) { $substvar{"F:$f"}= $f{$f}; }
+
for $f (qw(Section Priority)) {
$spvalue{$f}= $spdefault{$f} unless length($spvalue{$f});
$f{$f}= $spvalue{$f} if $spinclude{$f} && length($spvalue{$f});
8ainer Description Architecture)) {
defined($f{$f}) || &warn("missing information for output field $f");
}
-$oppackage= $f{'Package'};
$verdiff= $f{'Version'} ne $sourceversion;
if ($oppackage ne $sourcepackage || $verdiff) {
--- dpkg-source.pl 2000/06/25 10:33:13 1.1
+++ dpkg-source.pl 2000/06/25 10:37:13
@@ -115,6 +115,7 @@
$controlfile= "$dir/debian/control" unless defined($controlfile);
&parsechangelog;
+ &parsevarlistfile;
&parsecontrolfile;
$f{"Format"}=$dscformat;
--- End Message ---