#!/usr/bin/perl -CSAL

use strict;
use warnings;


if( @ARGV && $ARGV[0] =~ /^--?h(?:elp)?$/i ) {
    print <<EOF;
usage: nl.pl [ <start> ] [ <file...> ]
Numbers lines in plain text files or stdin, starting with <start>.  <start>
gives the first line number (non-negative, in decimal) and format if present.
<start> must contain exactly one sequence of digits, which will be incremented
for each file.  The width of the number and immediately preceding zeros or
white space will be kept constant while the number fits into that width.  The
default <start> is "   1 ", i.e.  space-padded to width 4, right-aligned,
starting with 1 and followed by a single space.
EOF
    exit;
}

# old more restricted variant:
# The format may contain leading spaces or zeros and trailing white space.
# $ARGV[0] =~ /^( *)(0*)(\d+)(\s*)$/
# $format= length($2) ? "$1%0".length($2.$3)."d$4%s" : "%".length($1.$3)."d$4%s";

my ($format, $linenum);
if( @ARGV && ! -e $ARGV[0] && $ARGV[0] =~ /^([^\d\/]*[^\d\/\s])?(\s*)(\d+)([^\d\/]*)$/ ) {
    my ($pre, $spad, $digs, $suff)= ($1 // "", $2, $3, $4);
    $pre =~ s/%/%%/g;
    $suff =~ s/%/%%/g;
    $format= $digs =~ /^0/ ? "$pre$spad%0".length($digs)."u$suff%s" : "$pre%".length($spad.$digs)."u$suff%s";
    $linenum= 0 + $digs;
    shift @ARGV;
}
elsif( @ARGV && ! -e $ARGV[0] ) {
    die "\`$ARGV[0]' is not a legal format but does not exist.\n";
}
else {
    $format= "%4d %s";
    $linenum= 1;
}

while( <> ) {
    printf($format, $linenum, $_);
    ++$linenum;
}

