=head1 NAME
makepp_builtins -- Builtin commands in makepp
=
for
vc
$Id
: makepp_builtins.pod,v 1.37 2008/07/30 23:13:36 pfeiffer Exp $
=head1 DESCRIPTION
I<L<B<a>wk|/awk>>,E<nbsp>
L<
&B
<c>at|/
&cat
>, I<L</chgrp>>, L</
&chmod
>, I<L<
chown
|/chgrp>>, L</
&cp
>, L</
&cut
>,E<nbsp>
L<
&B
<e>cho|/
&echo
>, L</
&expr
>,E<nbsp>
I<L<B<f>alse|/false>>,E<nbsp>
L<
&B
<g>rep|/
&grep
>,E<nbsp>
I<L<B<h>ead|/head>>,E<nbsp>
L<
&B
<i>nstall|/
&install
>,E<nbsp>
L<
&B
<l>n|/
&ln
>,E<nbsp>
L<
&B
<m>kdir|/
&mkdir
>, L</
&mv
>, I<L</m4>>,E<nbsp>
L<
&B
<p>erl|/
&grep
>, L</
&preprocess
>, L<
&printf
|/
&echo
>,E<nbsp>
L<
&B
<r>m|/
&rm
>, I<L</
rmdir
>>,E<nbsp>
L<
&B
<s>ed|/
&grep
>, L</
&sort
>,E<nbsp>
I<L<B<t>ail|/head>>, L</
&template
>, L</
&touch
>, I<L</
tr
>>,E<nbsp>
L<
&B
<u>ninstall|/
&uninstall
>, L</
&uniq
>,E<nbsp>
L<
&B
<y>es|/
&echo
>
There is a special Shell-like possibility to call built-in commands in a rule.
The only metacharacters recognized are comment signs, backslashes, single and
double quotes. Only one command may be
given
per line, and I/O redirection is
not available (see C<-i> and C<-o> below instead).
These commands start
with
C<&>, which is the function character in Perl and
not a valid first character in Shell. If
no
builtin command of that name can
be found, this is also the syntax
for
calling an external script within the
Perl instance performing the rule. See L<run|makepp_extending/run>.
These commands, as well as your self
defined
ones and perl scripts can also be
called as a make function, returning the standard output. The newlines are
converted to spaces, except
when
evaluated within a C<define> statement.
FIRST-WORDS ;= $(
&cut
-d
' '
-f0 $(FILES))
When these commands are not indented as rule actions, they get
L<performed|makepp_statements/Commands>
while
reading the makefile. You can
also access these commands stand-alone, e.g.
if
you need some features not
available in the Unix counterpart, via the L<makeppbuiltin|makeppbuiltin>
command.
These commands are mostly based on the GNU variant. But many options (like
--backup, --interactive or --recursive) don't really make sense in a makefile.
So, even though they'd be easy to implement in Perl, they have been left out.
Also many Unix commands offer a variety of options that cover fairly
complicated cases (e.g.
sort
field specifications)
while
still being
inherently limited. Allowing access to Perl, which is present anyway, gives
much more power here.
Lists of filenames may be empty, making it safe to call these commands
with
an
unchecked list. Options in their short form may be glued together as in
C<-ab> instead of C<-a -b>. Arguments to options are only shown
for
the long
form, but they also apply to the short form. In the long form they may be
given
either glued on
with
an C<=> sign or separately. In the short form they
may be
given
either glued on directly or separately. A few options are common
to several builtins, though the short form is sometimes not available:
=over
=item -A filename
=item --args-file=filename
=item --arguments-file=filename
Read the file and parse it as possibly quoted options on one or several lines.
=item -f
=item --force
Force the creation of the file(s) intended by the parameters, even
if
a
different kind of file or empty directory of that name already
exists
. This
must precede the C<-o, --output=filename> option
if
it is to have any effect
on that.
=item -i shellcommand
=item --inpipe=shellcommand
Start the Shell command(s) and
pipe
the output into the builtin. There may
optionally be a trailing C<|> character, to indicate this is a
pipe
. With
this option
no
filenames need to be
given
. But
if
you want to perform the
builtin on both files and the
pipe
output, you must
use
C<-> as a filename
for
the
pipe
output. This option is necessary because there is
no
redirection
syntax.
=item -I
=item --infail
If an C<--inpipe> Shell command fails, that also causes the current builtin to
fail.
=item -o filename
=item --output=filename
Write the output to this file, rather than stdout. Filename may have any of these forms:
=over
=item filename
=item >filename
Simply
write
to file.
=item >>filename
Append to (not necessarily) existing file.
=item +<filename
Also
open
the file
for
input, allowing inplace editing. With this option
variant
no
input filenames need to be
given
. But
if
you want to perform the
builtin on more files, you must
use
C<-> as an input filename
for
this one.
In fact the ouptut gets written to a temporary file which gets moved to
filename at the end.
=item |shellcommand
Pipe the builtin's output to the Shell command(s).
=back
This option is necessary because there is
no
redirection syntax.
=item -O
=item --outfail
If an C<--output> Shell command fails, that also causes the current builtin to
fail.
=item -r number
=item --record-size=number
Locally sets C<$/>
for
the current builtin. This splits input into records of
length
I<number> rather than line by line. If I<number> is zero,
each
input
file as a whole is one record.
=item -s string
=item --separator=string
Locally sets C<$/>
for
the current builtin. This splits input on I<string>
rather than line by line.
=item -S
=item --synclines
Generate C<
understood by many C-like languages.
=item -v
=item --verbose
Document the changes to the file
system
. This must precede other options
if
it is to document their effect. If you pass this option to makepp itself, it
is as
if
you had
given
it
for
every single builtin command.
=back
There are two motivations
for
having builtin commands in makepp. The first is
to offer a set of utilities, which, unlike Shell commands, are guaranteed to
work the same everywhere, like C<
&echo
-n> or C<
&mkdir
-p>, and saving you the
hassle of finding the path to C<
&install
> and figuring out its wildly varying
options. In a compilation environment, it's useful to have the C<--synclines>
option, which normally only C<m4> provides, on all filters.
The other is a question of efficiency. In general costly
fork
/execs should be
avoided where reasonably possible. On Unix emulations like Cygwin or
BS2000/Posix, this becomes a noticeable win. But, even on Linux,
when
the
makepp test suite was converted from external commands to builtins, there was
an overall saving of 3% user CPU usage and 15%
system
CPU usage. (The tests
are of course heavy on primitive actions and hardly call the compiler.)
Consistency is also an issue, though we're not going to reform Unix. Normally
commands have various nuances of regular expressions. And many invent
sort
of
languages,
each
different of course,
for
doing something (e.g. C<expr>, C<sed>
...), or complex options
for
specifying fields, delimiters, columns
(e.g. C<cut>, C<
sort
> ...).
Here instead, anything fancy simply gets handled by Perl, giving both
consistency across all commands, and far more power than a whole bunch of
options. Better yet, any I<Perlcode> these commands run
for
you, gets run in
the
package
of the Makefile. So, rather than stuff Perl code into the rule
action, you can define functions and variables and
use
them within the
commands:
sub
my_filter {
}
%.out: %.in Makeppfile
&grep
&my_filter
$(input) -o $(output)
If you
use
perl functions or variables in your commands, makepp does not
recognize this as a dependency. It is generally safer to
tell
makepp
everything, so rules which
use
Perl elements should depend on the makefile or
module providing those elements, as shown in the above example.
On the other hand ingnorance may be desirable
if
you have a program that mixes
programatic and configuration aspects in one file. An example would be a WSDL
file containing both a web service interface definition and an IP address.
You could preprocess this file
with
the C<
&template
> command to patch in the
configuration, but not let makepp notice.
=over
=item awk
Not built in, but L<C<
&sed
>|/_26grep> is comparable.
=item
&cat
[option ...] filename ...
Concatenates all the files into a single one.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force,
-i, --inpipe=shellcommand, -I, --infail, -o, --output=filename, -O, --outfail,
-S, --synclines, -v, --verbose>
=item chgrp,
chown
These commands are mostly not portable! They will either quietly
do
nothing
or fail, depending on the
system
. Generally only root may perform these
operations, which is why they are only available through the L<C<
&install
>|/_26install>
command.
=item
&chmod
[option ...] mode filename ...
Sets I<mode>
for
all
given
files. Mode must be an octal string.
Standard options: C<-A, --args-file, --arguments-file=filename, -v, --verbose>
=item
&cp
[option ...] sourcefile destfile
=item
&cp
[option ...] sourcefile
=item
&cp
[option ...] sourcefile ... destdir
Copy I<sourcefile> to I<destfile>, one I<sourcefile> to current directory or
multiple I<sourcefile>s to I<destdir>
with
the same name.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -v,
--verbose>
=over
=item -l
=item --
link
Try to
link
the files. If that fails, copy.
=back
=item
&cut
[option ...] filename ...
Print selected parts of lines from
each
file or selected lines, counting
across all files. The output is separated by the delimiter which defaults to
TAB
for
fields and empty string
for
characters.
Standard options: C<-A, --args-file, --arguments-file=filename, --force, -i,
--inpipe=shellcommand, -I, --infail, -o, --output=filename, -O, --outfail, -r,
--record-size=number, --separator=string, -S, --synclines, -v, --verbose>
=over
=item -c list
=item --characters=list
Print all the characters specified by I<list>. I<List> may be any Perl
expression returning a list of integers. The integers can be either positive,
starting at zero to count from the beginning, or negative to count from the
end. Unlike Unix C<cut>, the order you request is respected.
Unlike in Perl's slice operator where a
".."
range must be either positive or
negative, C<
&cut
> allows starting
with
a positive and ending
with
a negative.
But this is only available
if
your expression consists only of numbers, commas
and
".."
. E.g. C<1..-2> means everything but the first (0) and the
last
(-1).
The list expression can look at the whole line in C<
$_
>. Changes to that will
be ignored, however, because
when
this expression is evaluated the line
has
already been
split
to Perl's autosplit variable C<@::F>. The numbers you
return
are in fact indices to that list.
=item -d string
=item --delimiter=string
Set a new delimiter
for
input fields and output. Unlike Unix C<cut>, this may
have any
length
.
=item -E
=item --noescape
Treat C<\> as normal literals
for
C<-p, --
printf
=
format
>.
=item -f list
=item --fields=list
Print all the groups specified by I<list>. I<List> is as described under
C<-c, --characters=list>. Note that this hides the standard option C<-f>
which must be
given
as C<--force>.
=item -l list
=item --lines=list
Print all the lines specified by I<list>. I<List> is as described under C<-c,
--characters=list>
with
one major difference: The first line
has
number 1,
there is
no
line 0. This is definitely inefficient
for
big files,
if
you have
a mixed positive to negative range in your list, as it reads everything to
memory. Otherwise Perl could optimize this, but I don't know
if
it does.
=item -m
=item --matching
Print only matching lines, i.e. ones which have enough characters or fields.
This implies C<--only-delimited>, which is why you will miss single-field
lines
with
C<--fields=0>.
=item -p
format
=item --
printf
=
format
Apply
format
(
with
\escapes) to all fields or characters.
=item -s
=item --only-delimited
Print only lines containing delimiters.
=back
&cut
-c 10-20,-5,25- $(input)
&cut
-d: --fields 0,4 --
printf
=
'%10s is %s\n'
/etc/passwd
=item
&echo
[option ...] string ...
=item
&printf
[option ...]
format
argument ...
=item
&yes
[option ...] string ...
Writes all strings to stdout or the
given
outfile. Both C<
&echo
> and C<
&yes
>
add a newline at the end. The strings, or
for
C<
&printf
> the
format
, may
contain C<\> escapes, as they are known from C or modern Unix or Shell
C<echo>. They are however as in Perl double-quotes, which means some
differences, like that a single trailing C<\> is not allowed. Perl
has
a few
more interesting escapes, but the ones you might expect to
do
something
different are:
=over
=item \cA
Is a control character ^A.
=item \u
Upcases the following letter.
=item \U
Upcases the rest, or upto the
next
C<\L>
if
found.
=item \xHH, \x{HHHH}
Is the character value of the
given
Hex code. Note that numeric codes are not
portable to EBCDIC platforms!
=back
Unlike Unix C<yes>, C<
&yes
> is exactly like C<
&echo
>, except that it repeats
the output
for
as long as it can, typically
until
an C<--output
'| I<command>'
>
terminates. And,
if
C<
&yes
>
has
no
arguments, it defaults to C<y>.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -o,
--output=filename, -O, --outfail, -v, --verbose>
=over
=item -E
=item --noescape
Treat C<\> as normal literals.
=item -n
=item --nonewline
Do not add a newline
after
the
last
string. (Not understood by C<
&printf
>.)
=back
=item
&expr
[option ...] perlcode ...
Print the
scalar
value of perlcode, which may be written as one or several
arguments. Note that builtin commands are not parsed by the Shell, so C<*>,
C<(> or C<< > >> are not special. But string quotes are parsed by makepp, so
Perl strings must be quoted twice,
unless
you want to
use
barewords. If the
value is false, this fails. Note that, unlike in Unix C<expr> Perl's
index
function starts at 0 (false) and returns -1 (true)
for
failure.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -o,
--output=filename, -O, --outfail, -v, --verbose>
=over
=item -n
=item --nonewline
Do not add a newline
after
the output.
=back
&expr
($(VAR) - 3) * 2 < 1 && -1 || 1
&expr
"$(VAR) - 3 * 2 < 1 ? 'joy' : 'sorrow'"
-o $(output)
-
&expr
$(VAR) - 3 * 2 -o >>$(output)
=item false
Not very constructive and thus not built in, but L<C<
&expr
>|/_26expr>
with
no
argument or C<0> is comparable.
=item
&grep
[option ...] perlcode filename ...
=item
&perl
[option ...] perlcode filename ...
=item
&sed
[option ...] perlcode filename ...
All the files get
read
line by line (
unless
you gave a C<--separator> option),
and I<perlcode> gets evaluated
for
each
line,
before
it gets printed. C<
&sed
>
is similar to C<perl -pe>,
while
C<
&grep
> only outputs those lines
for
which
I<perlcode> returns a true value. C<
&perl
> is similar to C<perl -ne>, only
outputting whatever you explicitly
print
in the I<perlcode>. The line content
is available in C<
$_
>, which may be modified.
Of these three, only C<
&grep
> will fail
if
it outputs nothing. Note that
there is
no
ignore-case option, since you would
do
that
with
C</I<regexp>/i>.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -i,
--inpipe=shellcommand, -I, --infail, -o, --output=filename, -O, --outfail, -r,
--record-size=number, -s, --separator=string, -S, --synclines, --verbose>
The option C<--synclines> only makes sence
with
C<
&perl
>
if
you
use
C<
&Makecmds::print
> to output C<
$_
>. Only C<
&grep
>
has
extra options:
=over
=item -c
=item --count
Suppress normal output; instead
print
a count of matching lines. With the C<-v,
--invert-match> option (see below), count non-matching lines.
=item -l
=item --list
=item --files-
with
-matches
Output only the name of those files
with
matches. When this is combined
with
C<-v, --invert-match>, output the name of files
with
lines that don't match (a
bit absurdly but compatible
with
Unix -vl). When this is combined
with
a
doubled C<-vv>, output the name of files
with
no
matches.
=item -v
=item --vice-versa
=item --revert-match
=item --invert-match
Invert the sense of matching, to
select
non-matching lines. Note that this
hides the standard option C<-v> which must be
given
as C<--verbose>.
=item -w filename
=item --waste-file=filename
An optional waste basket
for
collecting the rejected lines. This is not only
for
debugging your selection code, but also
for
splitting your input in two.
As
with
the normal output, you may modify
$_
before
returning false.
=back
&sed
s/foo/bar/ f1 f2 f3 -o outfile
&sed
'$$_ = uc'
f1 f2 f3 -o outfile
&grep
'$$. % 3'
f1 f2 f3 -o outfile
&grep
-c /match/i f1 f2 f3
=item head
=item tail
These are not provided, but you can achieve the same result
with
L<C<
&grep
>|/_26grep> or
L<C<
&cut
--lines>|/_26cut>:
&grep
1..10 file
&grep
10..
eof
file
&cut
--lines -10..-1 file
Note that 1..10 in C<
&grep
> is Perl's line number flip-flop operator, which
annoyingly starts at 1. Don't start at 0, or the flip-flop will never become
true.
=item
&install
[option ...] sourcefile destfile
=item
&install
[option ...] sourcefile ... destdir
=item
&install
--directory [option ...] directory ...
Move or
rename
I<sourcefile> to I<destfile>, or multiple I<sourcefile>s to
I<destdir>
with
the same name. This is the preferred way of transferring
build results to their final installation locations.
Every file
system
modification performed by C<
&install
> gets logged to the end
of the file pointed to by the environment variable C<
$INSTALL_LOG
>, or,
if
that is not set but we are under a directory
with
a F<RootMakeppfile(.mk)>, to
a file of F<.install_log> in that directory, or
else
to that file in the
current directory. You may want to
delete
the logfile
before
a series of
C<
&install
> invocations.
Standard options: C<-A, --args-file, --arguments-file=filename, -v, --verbose>
=over
=item -c
=item --copy
Copy the files rather than moving them. This is preferable, as it doesn't
force makepp to rebuild the file
next
time
. But it is not the
default
,
for
compatibility
with
other install programs.
=item -d
=item --directory
In the third form form of this command create all the
given
directories and
any necessary parent directories.
=item -g group
=item --group=group
Change the group ownership of the destination files. The group may be
given
by name or numerically.
=item -l
=item --
link
Try to
link
the files. If that fails, copy.
=item --
log
=filename
=item --logfile=filename
Use I<filename> instead of normal logfile.
=item -m mode
=item --mode=mode
Sets I<mode>
for
all destination files or directories. Mode must be an octal
string.
=item -o owner
=item --owner=owner
Change the ownership of the destination files. The owner may be
given
by name
or numerically.
=item -r
=item --resolve
=item --resolve-symbolic
=item --resolve-symbolic-
link
=item --resolve-
symlink
=item -S
=item --symbolic
=item --symbolic-
link
=item --
symlink
Creates symbolic links instead of moving. These options are passed to
L<C<
&ln
>|/_26ln> and are described there.
=item -s
=item --strip
Calls the C<strip> utility, which must be in the C<
$PATH
>, on the destination
files.
=back
=item
&ln
[option ...] sourcefile destfile
=item
&ln
[option ...] sourcefile
=item
&ln
[option ...] sourcefile ... destdir
Link I<sourcefile> to I<destfile>, one I<sourcefile> to current directory or
multiple I<sourcefile>s to I<destdir>
with
the same name.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -v,
--verbose>
=over
=item -r
=item --resolve
=item --resolve-symbolic
=item --resolve-symbolic-
link
=item --resolve-
symlink
This is what you always wanted C<ln -s> to
do
. Create symbolic rather than
hard links, not to the strings specified, but really to the
given
files.
=item -s
=item --symbolic
=item --symbolic-
link
=item --
symlink
Create symbolic rather than hard links.
=back
Note that on various file or operating systems, this operation is not
supported. To get at least some
sort
of result, C<
&ln
> can copy the files
for
you instead (not directories though). To achieve this, you need to export the
following variable
before
calling C<makepp>:
=over
=item export MAKEPP_LN_CP=1
C<
&ln
> --resolve or --symbolic will copy the files instead of creating a
symbolic
link
.
=item export MAKEPP_LN_CP=2
C<
&ln
> will copy the files instead of creating a hard
link
.
=item export MAKEPP_LN_CP=3
All invocations of C<
&ln
> will copy the files instead of creating either kind
of
link
.
=back
=item
&mkdir
[option ...] directory ...
Create the directories.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -v,
--verbose>
=over
=item -m mode
=item --mode=mode
Sets I<mode>
for
all created directories, irrespective of the
umask
. Mode
must be an octal string. If this is not
given
, the mode defaults to 755.
=item -p
=item --parent
Also create any necessary parent directories. Ignore directory creation
failure due to the directory already existing (even
if
it was created
concurrently by another process).
=back
=item
&mv
[option ...] sourcefile destfile
=item
&mv
[option ...] sourcefile
=item
&mv
[option ...] sourcefile ... destdir
Move or
rename
I<sourcefile> to I<destfile>, one I<sourcefile> to current
directory or multiple I<sourcefile>s to I<destdir>
with
the same name.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -v,
--verbose>
=item m4
Not built in, but L<C<
&preprocess
>|/_26preprocess> is, and
L<C<
&template
>|/_26template> is almost as powerful.
=item
&preprocess
[option ...] variable=definition ... filename ...
This preprocesses the files exactly the same way makepp does
for
makefiles.
This is more powerful than L<C<
&template
>|/_26template> but syntactically not
suited to files
with
lots of C<$>-signs, like Makefiles or scripts.
L<Conditional statements|makepp_statements/Conditionals>, as well as the
statements C<include>/C<_include> (which here neither build the file nor
search upwards), C<perl>/C<makeperl>/C<perl_begin> or C<
sub
>/C<makesub>, or
any statements you define within the file, are processed. Empty and comment
lines are eliminated.
But, instead of learning build rules, it will output all remaining lines
after
C<$(...)> expression expansion. To prevent statement from being recognizeded
as such, you can precede them
with
an empty expression C<$()>. The same
applies to lines you want to stay empty or which shall retain a leading
comment sign. Likewise,
if
a trailing backslash is not to
join
a line
with
the
next
, put C<$()>
after
it.
A normal line gets output as is.
A line
with
$(MAKEEXPRESSIONS) gets expanded and output.
ifdef WANTTHIS
might not get output
endif
include some files
_include some files that might not exist
$()include empty expression prevents keyword from being recognized.
$()
$()
Empty expression prevents \$()
backslash continuation from being recognized.
might give:
A normal line gets output as is.
A line
with
whatever gets expanded and output.
lots of slurped in content here...
include empty expression prevents keyword from being recognized.
Empty expression prevents \
backslash continuation from being recognized.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -o,
--output=filename, -O, --outfail, -S, --synclines, -v, --verbose>
=over
=item -a
=item --assignment
Also treat assignments within the files as makepp would. Alas such lines
can't be masked
with
an empty C<$()>, because it is legal to construct
variable names
with
expressions. This additionally recognizes the statements
C<define>, C<export>/C<unexport> and C<
override
> (these can be masked
with
C<$()>).
=item -h \\
%hash
=item --hashref=\\
%hash
This allows preallocation of the variable
values
, including long ones not easily
passed in a command. The passed expression may be any Perl code that returns
a hash reference. This is merged
with
any other variables passed to the command,
including from another C<--hashref> option.
=back
=item
&rm
[option ...] filename ...
Delete files
if
you have directory
write
permission. This is what Unix
C<rm -f> would
delete
, since it
has
a special protection
for
interactive
use
not needed in a Makefile.
Standard options: C<-A, --args-file, --arguments-file=filename, -v, --verbose>
=over
=item -f
=item --force
This prevents complaining about inexistent files. That is a side effect this
option
has
in Unix, and the only one that makes sense here.
=item -m
=item --metainfo
In addition to the
given
files, this also deletes the meta information makepp
stores about them in the .makepp directory. Thus makepp forgets all it ever
knew about the
given
files. If the .makepp directory becomes empty
after
this, it too is deleted.
=back
This will also
delete
given
directories, but only
if
they are empty. To
facilitate this, it will
delete
directories
last
, in the order of descending
depth. So you can
use
C<**> expressions to
delete
whole hierarchies. Here's
an example to be found in many top level make files. Note that there is a
L<C<makeppclean>|makeppclean> utility that can
do
this more efficiently.
$(phony cleanold):
&rm
-fm $(only-stale **/*)
$(phony clean): cleanold
&rm
-f $(wildcard **/*.[ao])
$(phony distclean): clean
&rm
-fm $(only-targets **/*)
=item
rmdir
Not built in, but L<C<
&rm
>|/_26rm> can handle this.
=item
&sort
[option ...] filename ...
Sorts all files together in lexicographic order. This is inefficient
for
rather big files, because it happens completely in memory. It will fail
if
the combined size of all files exceeds the memory you are entitled to.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -i,
--inpipe=shellcommand, -I, --infail, -o, --output=filename, -O, --outfail,
--record-size=number, -s, --separator=string, -v, --verbose>
=over
=item -c perlcode
=item --compare=perlcode
I<perlcode> represents a Perl
sort
block,
with
the two sorting candidates in
C<
$a
> and C<
$b
>.
=item -n
=item --numeric
=item --numeric-
sort
This sorts sorts numerically on the beginnings of records. Leading whitespace
is skipped. You can
use
C<--transform> and C<--detransform>
if
the numbers
are not at the beginning.
=item -r
=item --
reverse
Output the results in the
reverse
order. Note that this hides the standard
option C<-r> which must be
given
as C<--record-size>.
=item -t perlcode
=item --transform=perlcode
=item -d perlcode
=item --detransform=perlcode
If you have a complex code, sorting gets more and more expensive in proportion
to the number of records I<n>, because the code gets called O(I<n>
log
(I<n>))
times
. To avoid that, you can allow Perl to concentrate on sorting, by first
modifying the strings, such that complicated search criteria extraction
happens once per record, and modifying them back, once they are sorted.
If these options are
given
, the C<--transform> I<perlcode> gets mapped to the
records in C<
$_
> one
after
another, and can modify them. After sorting, the
C<--detransform> I<perlcode> gets mapped to the modified records in C<
$_
> one
after
another, and can modify them back. You will usually
use
neither or both
of these options,
unless
you want to output modified lines.
Turning the strings into a structure of extracted
sort
criteria, which your
C<--compare> I<perlcode> can pick up is known as the Schwartzian Transform
(ST). Packing everything into the string itself, so that
no
C<--compare>
I<perlcode> is needed, allowing the whole sorting to happen without performing
expensive Perl code, is known as the Guttmann-Rosler Transform (GRT). You can
find tips by searching
for
those names on the web.
&sort
--compare
'eval( $$a ) <=> eval( $$b )'
$(input) -o >>$(output)
&sort
-t
'$$_ = [lc, $$_]'
-c
'$$a->[0] cmp $$b->[0]'
-d
'$$_->[1]'
$(input) -o >>$(output)
&sort
-t
&transform
-d
&detransform
$(input) -o >>$(output)
=item -u
=item --uniq
=item --unique
After sorting, eliminate duplicates. These are either identical lines, or
if
the C<--compare> option is
given
, ones which that I<perlcode> reports as
equivalent.
=back
=item
&template
[option ...] macro=definition ... filename ...
This is a macro preprocessor, not quite as powerful as C<m4>, but covers more
than is found in many makefiles. See L<C<
&preprocess
>|/_26preprocess>
for
a
more powerful alternative. Any normal text goes through unchanged. It
replaces all occurences of C<
@macro
@>, C<
@macro
(arg1,arg2...)@> or everything
between C<@
@macro
@@>, C<@
@macro
(arg1,arg2...)@@> and C<@@>
with
I<definition>.
If there are args, they replace C<$1> through C<$9> or C<${I<number>}> in
I<definition>. One level of macro nesting is possible in that the args in
parenthesis may contain plain C<
@macro
@> invocations, as in C<
@f
(
@x
@)@>, where
@x
@ gets expanded
before
being replaced into the body of C<f>.
The simple C<@...@> cases are single line, but may mask a trailing newline
if
the closing C<@> is immediately followed by a backslash. The multiline
C<@@...@@> cases must also fit on one line, but the corresponding C<@@> may be
on a different line. This is useful
if
you have a workaround code block in an
unprocessed script, which is to get replaced
with
the configured code.
In addition to passing macro definitions on the command line, you can also put
C<
@macro
=definition@> or C<
@macro
?=definition@> into the file. The latter
only takes effect
if
the macro was not
defined
, presumably on the command
line. You can also call C<@{ I<Perlcode> }@> or C<@@{ I<Perlcode> }@@ ... @@>
in the file. The Perl variable C<
$ARGV
> contains the name of the current
input file. If you call C<
@macro
{ I<Perlcode> }@>, then you define a new
macro, the body of which is a perl
sub
. The arguments,
if
there are any, get
passed in as C<
@_
>.
@m1
=some definition@\
@m2
=foo $1 bar@\
@middle_of_arg
=iddl@\
@m1
@
@m2
(m
@middle_of_arg
@e
)@
@
@m2
(many lines)@@
...
@@ plain text 1 + 2 = @{ 1 + 2 }@
becomes
some definition foo middle bar
foo many lines bar plain text 1 + 2 = 3
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force,
-i, --inpipe=shellcommand, -I, --infail, -o, --output=filename, -O, --outfail,
-S, --synclines, -v, --verbose>
=over
=item -h \\
%hash
=item --hashref=\\
%hash
This allows preallocation of the macro
values
, including long ones not easily
passed in a command. The passed expression may be any Perl code that returns
a hash reference. This is merged
with
any other macros passed to the command,
including from another C<--hashref> option. A hash value may also be a code
reference, in that case the function gets called, as
with
C<
@macro
{
I<Perlcode> }@> definitions.
=item -s /prefix/suffix/
=item --simple=/prefix/suffix/
This replaces C<@>
before
and
after
I<var>
with
I<prefix> and I<suffix>
respectively. The first character is the separator and need not be a slash.
=item -m /prefix/suffix/afterprefix/[aftersuffix/]
=item --multiline=/prefix/suffix/afterprefix/[aftersuffix/]
This replaces C<@@>
before
and
after
I<var> and at the end of the block
with
I<prefix>, I<suffix> and I<afterprefix> respectively. If I<aftersuffix> is
also
given
, the I<var> name must get repeated
before
it. The first character
is the separator and need not be a slash. E.g. an XML-ish
--simple=|<|/>| --multiline=|<|>|</|>|
=item -d
=item --
defined
Replace only instances of macros which are actually
defined
.
=back
=item
&touch
[option ...] filename ...
Updates the modification and access timestamps of
each
file to now. If the
file doesn't exist, it gets created.
Standard options: C<-A, --args-file, --arguments-file=filename, -v, --verbose>
=item
&uninstall
[option ...] [filename ...]
Uninstall files previously installed by L<C<
&install
>|/_26install>. The
I<filename>s are logfiles written by C<
&install
>. If none are
given
, nor an
C<--inpipe> option, reads the
default
logfile of C<
&install
>.
Standard options: C<-A, --args-file, --arguments-file=filename, -i,
--inpipe=shellcommand, -I, --infail, -v, --verbose>
=item
&uniq
[option ...] filename ...
Discard all but one of successive equal lines.
Standard options: C<-A, --args-file, --arguments-file=filename, -f, --force, -i,
--inpipe=shellcommand, -I, --infail, -o, --output=filename, -O, --outfail, -r,
--record-size=number, -s, --separator=string, -S, --synclines, -v, --verbose>
=over
=item -c perlcode
=item --compare=perlcode
This I<Perlcode> gets the previous and current lines in C<
$a
> and C<
$b
> and
shall
return
true
if
it considers the two lines equal.
=back
&uniq
--compare=
'lc( $$a ) eq lc $$b'
$(inputs) -o $(output)
=item
tr
Not built in, but L<C<
&sed
>|/_26grep> can handle this.
=back
=head1 AUTHOR
Daniel Pfeiffer (occitan
@esperanto
.org)