/* nl -- number lines of files
- Copyright (C) 89, 92, 1995-2000 Free Software Foundation, Inc.
+ Copyright (C) 89, 92, 1995-2003 Free Software Foundation, Inc.
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
#include <getopt.h>
#include "system.h"
-#include "closeout.h"
#include <regex.h>
#include "error.h"
#include "linebuffer.h"
+#include "quote.h"
#include "xstrtol.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "nl"
-#define AUTHORS "Scott Bartram and David MacKenzie"
+#define WRITTEN_BY _("Written by Scott Bartram and David MacKenzie.")
#ifndef TRUE
# define TRUE 1
Usage: %s [OPTION]... [FILE]...\n\
"),
program_name);
- printf (_("\
+ fputs (_("\
Write each FILE to standard output, with line numbers added.\n\
With no FILE, or when FILE is -, read standard input.\n\
\n\
+"), stdout);
+ fputs (_("\
+Mandatory arguments to long options are mandatory for short options too.\n\
+"), stdout);
+ fputs (_("\
-b, --body-numbering=STYLE use STYLE for numbering body lines\n\
-d, --section-delimiter=CC use CC for separating logical pages\n\
-f, --footer-numbering=STYLE use STYLE for numbering footer lines\n\
+"), stdout);
+ fputs (_("\
-h, --header-numbering=STYLE use STYLE for numbering header lines\n\
-i, --page-increment=NUMBER line number increment at each line\n\
-l, --join-blank-lines=NUMBER group of NUMBER empty lines counted as one\n\
-n, --number-format=FORMAT insert line numbers according to FORMAT\n\
-p, --no-renumber do not reset line numbers at logical pages\n\
-s, --number-separator=STRING add STRING after (possible) line number\n\
+"), stdout);
+ fputs (_("\
-v, --first-page=NUMBER first line number on each logical page\n\
-w, --number-width=NUMBER use NUMBER columns for line numbers\n\
- --help display this help and exit\n\
- --version output version information and exit\n\
+"), stdout);
+ fputs (HELP_OPTION_DESCRIPTION, stdout);
+ fputs (VERSION_OPTION_DESCRIPTION, stdout);
+ fputs (_("\
\n\
By default, selects -v1 -i1 -l1 -sTAB -w6 -nrn -hn -bt -fn. CC are\n\
two delimiter characters for separating logical pages, a missing\n\
second character implies :. Type \\\\ for \\. STYLE is one of:\n\
+"), stdout);
+ fputs (_("\
\n\
a number all lines\n\
t number only nonempty lines\n\
rn right justified, no leading zeros\n\
rz right justified, leading zeros\n\
\n\
-"));
- puts (_("\nReport bugs to <bug-textutils@gnu.org>."));
+"), stdout);
+ printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
}
exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
static void
build_print_fmt (void)
{
- /* 12 = 10 chars for lineno_width, 1 for %, 1 for \0. */
- print_fmt = xmalloc (strlen (separator_str) + 12);
+ print_fmt = xmalloc ( 1 /* for `%' */
+ + 1 /* for `-' or `0' */
+ + INT_STRLEN_BOUND (lineno_width)
+ + 1 /* for `d' */
+ + 1 /* for trailing NUL byte */ );
switch (lineno_format)
{
case FORMAT_RIGHT_NOLZ:
- sprintf (print_fmt, "%%%dd%s", lineno_width, separator_str);
+ sprintf (print_fmt, "%%%dd", lineno_width);
break;
case FORMAT_RIGHT_LZ:
- sprintf (print_fmt, "%%0%dd%s", lineno_width, separator_str);
+ sprintf (print_fmt, "%%0%dd", lineno_width);
break;
case FORMAT_LEFT:
- sprintf (print_fmt, "%%-%dd%s", lineno_width, separator_str);
+ sprintf (print_fmt, "%%-%dd", lineno_width);
break;
}
}
*typep = optarg++;
optlen = strlen (optarg);
regexp->allocated = optlen * 2;
- regexp->buffer = (unsigned char *) xmalloc (regexp->allocated);
+ regexp->buffer = xmalloc (regexp->allocated);
regexp->translate = NULL;
regexp->fastmap = xmalloc (256);
regexp->fastmap_accurate = 0;
return rval;
}
-/* Print and increment the line number. */
+/* Print the line number and separator; increment the line number. */
static void
print_lineno (void)
{
printf (print_fmt, line_no);
+ fputs (separator_str, stdout);
line_no += page_incr;
}
blank_lines = 0;
}
else
- printf (print_no_line_fmt);
+ fputs (print_no_line_fmt, stdout);
}
else
print_lineno ();
if (1 < line_buf.length)
print_lineno ();
else
- printf (print_no_line_fmt);
+ fputs (print_no_line_fmt, stdout);
break;
case 'n':
- printf (print_no_line_fmt);
+ fputs (print_no_line_fmt, stdout);
break;
case 'p':
if (re_search (current_regex, line_buf.buffer, line_buf.length - 1,
0, line_buf.length - 1, (struct re_registers *) 0) < 0)
- printf (print_no_line_fmt);
+ fputs (print_no_line_fmt, stdout);
else
print_lineno ();
break;
static void
process_file (FILE *fp)
{
- while (readline (&line_buf, fp))
+ while (readlinebuffer (&line_buf, fp))
{
switch ((int) check_section ())
{
{
int c, exit_status = 0;
size_t len;
+ int fail = 0;
+ initialize_main (&argc, &argv);
program_name = argv[0];
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
case 'h':
if (build_type_arg (&header_type, &header_regex) != TRUE)
- usage (2);
+ {
+ error (0, 0, _("invalid header numbering style: %s"),
+ quote (optarg));
+ fail = 1;
+ }
break;
case 'b':
if (build_type_arg (&body_type, &body_regex) != TRUE)
- usage (2);
+ {
+ error (0, 0, _("invalid body numbering style: %s"),
+ quote (optarg));
+ fail = 1;
+ }
break;
case 'f':
if (build_type_arg (&footer_type, &footer_regex) != TRUE)
- usage (2);
+ {
+ error (0, 0, _("invalid footer numbering style: %s"),
+ quote (optarg));
+ fail = 1;
+ }
break;
case 'v':
{
if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
/* Allow it to be negative. */
|| tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0, _("invalid starting line number: `%s'"),
- optarg);
- starting_line_number = (int) tmp_long;
+ {
+ error (0, 0, _("invalid starting line number: %s"),
+ quote (optarg));
+ fail = 1;
+ }
+ else
+ {
+ starting_line_number = (int) tmp_long;
+ }
}
break;
case 'i':
long int tmp_long;
if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
|| tmp_long <= 0 || tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0, _("invalid line number increment: `%s'"),
- optarg);
- page_incr = (int) tmp_long;
+ {
+ error (0, 0, _("invalid line number increment: %s"),
+ quote (optarg));
+ fail = 1;
+ }
+ else
+ {
+ page_incr = (int) tmp_long;
+ }
}
break;
case 'p':
long int tmp_long;
if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
|| tmp_long <= 0 || tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0, _("invalid number of blank lines: `%s'"),
- optarg);
- blank_join = (int) tmp_long;
+ {
+ error (0, 0, _("invalid number of blank lines: %s"),
+ quote (optarg));
+ fail = 1;
+ }
+ else
+ {
+ blank_join = (int) tmp_long;
+ }
}
break;
case 's':
long int tmp_long;
if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
|| tmp_long <= 0 || tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0,
- _("invalid line number field width: `%s'"),
- optarg);
- lineno_width = (int) tmp_long;
+ {
+ error (0, 0, _("invalid line number field width: %s"),
+ quote (optarg));
+ fail = 1;
+ }
+ else
+ {
+ lineno_width = (int) tmp_long;
+ }
}
break;
case 'n':
- switch (*optarg)
+ if (STREQ (optarg, "ln"))
+ lineno_format = FORMAT_LEFT;
+ else if (STREQ (optarg, "rn"))
+ lineno_format = FORMAT_RIGHT_NOLZ;
+ else if (STREQ (optarg, "rz"))
+ lineno_format = FORMAT_RIGHT_LZ;
+ else
{
- case 'l':
- if (optarg[1] == 'n')
- lineno_format = FORMAT_LEFT;
- else
- usage (2);
- break;
- case 'r':
- switch (optarg[1])
- {
- case 'n':
- lineno_format = FORMAT_RIGHT_NOLZ;
- break;
- case 'z':
- lineno_format = FORMAT_RIGHT_LZ;
- break;
- default:
- usage (2);
- break;
- }
- break;
- default:
- usage (2);
- break;
+ error (0, 0, _("invalid line numbering format: %s"),
+ quote (optarg));
+ fail = 1;
}
break;
case 'd':
section_del = optarg;
break;
case_GETOPT_HELP_CHAR;
- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, WRITTEN_BY);
default:
- usage (2);
+ fail = 1;
break;
}
}
+ if (fail)
+ usage (2);
+
/* Initialize the section delimiters. */
len = strlen (section_del);