(WRITTEN_BY): Rename from AUTHORS.
[platform/upstream/coreutils.git] / src / nl.c
index bb59458..63beb57 100644 (file)
--- a/src/nl.c
+++ b/src/nl.c
@@ -1,5 +1,5 @@
 /* nl -- number lines of files
-   Copyright (C) 89, 92, 1995-2001 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 N_ ("Scott Bartram and David MacKenzie")
+#define WRITTEN_BY _("Written by Scott Bartram and David MacKenzie.")
 
 #ifndef TRUE
 # define TRUE   1
@@ -181,7 +181,11 @@ Usage: %s [OPTION]... [FILE]...\n\
 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\
@@ -197,8 +201,10 @@ Mandatory arguments to long options are mandatory for short options too.\n\
       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\
@@ -218,7 +224,7 @@ FORMAT is one of:\n\
   rz   right justified, leading zeros\n\
 \n\
 "), stdout);
-      puts (_("\nReport bugs to <bug-textutils@gnu.org>."));
+      printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
     }
   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
 }
@@ -228,18 +234,21 @@ FORMAT is one of:\n\
 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;
     }
 }
@@ -265,7 +274,7 @@ build_type_arg (char **typep, struct re_pattern_buffer *regexp)
       *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;
@@ -280,12 +289,13 @@ build_type_arg (char **typep, struct re_pattern_buffer *regexp)
   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;
 }
 
@@ -339,7 +349,7 @@ proc_text (void)
              blank_lines = 0;
            }
          else
-           puts (print_no_line_fmt);
+           fputs (print_no_line_fmt, stdout);
        }
       else
        print_lineno ();
@@ -348,15 +358,15 @@ proc_text (void)
       if (1 < line_buf.length)
        print_lineno ();
       else
-       puts (print_no_line_fmt);
+       fputs (print_no_line_fmt, stdout);
       break;
     case 'n':
-      puts (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)
-       puts (print_no_line_fmt);
+       fputs (print_no_line_fmt, stdout);
       else
        print_lineno ();
       break;
@@ -390,7 +400,7 @@ check_section (void)
 static void
 process_file (FILE *fp)
 {
-  while (readline (&line_buf, fp))
+  while (readlinebuffer (&line_buf, fp))
     {
       switch ((int) check_section ())
        {
@@ -455,7 +465,9 @@ main (int argc, char **argv)
 {
   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);
@@ -475,15 +487,27 @@ main (int argc, char **argv)
 
        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':
          {
@@ -491,9 +515,15 @@ main (int argc, char **argv)
            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':
@@ -501,9 +531,15 @@ main (int argc, char **argv)
            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':
@@ -514,9 +550,15 @@ main (int argc, char **argv)
            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':
@@ -527,51 +569,45 @@ main (int argc, char **argv)
            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);