/* nl -- number lines of files                                                  This is the nl utility
   Copyright (C) 1989-2018 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         
   the Free Software Foundation, either version 3 of the License, or            
   (at your option) any later version.                                          
                                                                                
   This program is distributed in the hope that it will be useful,              
   but WITHOUT ANY WARRANTY; without even the implied warranty of               
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                
   GNU General Public License for more details.                                 
                                                                                
   You should have received a copy of the GNU General Public License            
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */   The GNUv3 license
                                                                                
/* Written by Scott Bartram (nancy!scott@uunet.uu.net)                          
   Revised by David MacKenzie (djm@gnu.ai.mit.edu) */                           
                                                                                
#include <config.h>                                                             Provides system specific information
                                                                                
#include <stdio.h>                                                              Provides standard I/O capability
#include <sys/types.h>                                                          Provides system data types
#include <getopt.h>                                                             ...!includes auto-comment...
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
                                                                                
#include <regex.h>                                                              ...!includes auto-comment...
                                                                                
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "fadvise.h"                                                            ...!includes auto-comment...
#include "linebuffer.h"                                                         ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "xdectoint.h"                                                          ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "nl"                                                       Line 38
                                                                                
#define AUTHORS \                                                               Line 40
  proper_name ("Scott Bartram"), \                                              Line 41
  proper_name ("David MacKenzie")                                               Line 42
                                                                                
/* Line-number formats.  They are given an int width, an intmax_t               
   value, and a string separator.  */                                           
                                                                                
/* Right justified, no leading zeroes.  */                                      
static char const FORMAT_RIGHT_NOLZ[] = "%*" PRIdMAX "%s";                      Line 48
                                                                                
/* Right justified, leading zeroes.  */                                         
static char const FORMAT_RIGHT_LZ[] = "%0*" PRIdMAX "%s";                       Line 51
                                                                                
/* Left justified, no leading zeroes.  */                                       
static char const FORMAT_LEFT[] = "%-*" PRIdMAX "%s";                           Line 54
                                                                                
/* Default section delimiter characters.  */                                    
static char const DEFAULT_SECTION_DELIMITERS[] = "\\:";                         Line 57
                                                                                
/* Types of input lines: either one of the section delimiters,                  
   or text to output. */                                                        
enum section                                                                    Line 61
{                                                                               
  Header, Body, Footer, Text                                                    Line 63
};                                                                              Block 1
                                                                                
/* Format of body lines (-b).  */                                               
static char const *body_type = "t";                                             Line 67
                                                                                
/* Format of header lines (-h).  */                                             
static char const *header_type = "n";                                           Line 70
                                                                                
/* Format of footer lines (-f).  */                                             
static char const *footer_type = "n";                                           Line 73
                                                                                
/* Format currently being used (body, header, or footer).  */                   
static char const *current_type;                                                Line 76
                                                                                
/* Regex for body lines to number (-bp).  */                                    
static struct re_pattern_buffer body_regex;                                     Line 79
                                                                                
/* Regex for header lines to number (-hp).  */                                  
static struct re_pattern_buffer header_regex;                                   Line 82
                                                                                
/* Regex for footer lines to number (-fp).  */                                  
static struct re_pattern_buffer footer_regex;                                   Line 85
                                                                                
/* Fastmaps for the above.  */                                                  
static char body_fastmap[UCHAR_MAX + 1];                                        Line 88
static char header_fastmap[UCHAR_MAX + 1];                                      Line 89
static char footer_fastmap[UCHAR_MAX + 1];                                      Line 90
                                                                                
/* Pointer to current regex, if any.  */                                        
static struct re_pattern_buffer *current_regex = NULL;                          Line 93
                                                                                
/* Separator string to print after line number (-s).  */                        
static char const *separator_str = "\t";                                        Line 96
                                                                                
/* Input section delimiter string (-d).  */                                     
static char const *section_del = DEFAULT_SECTION_DELIMITERS;                    Line 99
                                                                                
/* Header delimiter string.  */                                                 
static char *header_del = NULL;                                                 Line 102
                                                                                
/* Header section delimiter length.  */                                         
static size_t header_del_len;                                                   Line 105
                                                                                
/* Body delimiter string.  */                                                   
static char *body_del = NULL;                                                   Line 108
                                                                                
/* Body section delimiter length.  */                                           
static size_t body_del_len;                                                     Line 111
                                                                                
/* Footer delimiter string.  */                                                 
static char *footer_del = NULL;                                                 Line 114
                                                                                
/* Footer section delimiter length.  */                                         
static size_t footer_del_len;                                                   Line 117
                                                                                
/* Input buffer.  */                                                            
static struct linebuffer line_buf;                                              Line 120
                                                                                
/* printf format string for unnumbered lines.  */                               
static char *print_no_line_fmt = NULL;                                          Line 123
                                                                                
/* Starting line number on each page (-v).  */                                  
static intmax_t starting_line_number = 1;                                       Line 126
                                                                                
/* Line number increment (-i).  */                                              
static intmax_t page_incr = 1;                                                  Line 129
                                                                                
/* If true, reset line number at start of each page (-p).  */                   
static bool reset_numbers = true;                                               Line 132
                                                                                
/* Number of blank lines to consider to be one line for numbering (-l).  */     
static intmax_t blank_join = 1;                                                 Line 135
                                                                                
/* Width of line numbers (-w).  */                                              
static int lineno_width = 6;                                                    Line 138
                                                                                
/* Line number format (-n).  */                                                 
static char const *lineno_format = FORMAT_RIGHT_NOLZ;                           Line 141
                                                                                
/* Current print line number.  */                                               
static intmax_t line_no;                                                        Line 144
                                                                                
/* True if we have ever read standard input.  */                                
static bool have_read_stdin;                                                    Line 147
                                                                                
static struct option const longopts[] =                                         Line 149
{                                                                               
  {"header-numbering", required_argument, NULL, 'h'},                           Line 151
  {"body-numbering", required_argument, NULL, 'b'},                             Line 152
  {"footer-numbering", required_argument, NULL, 'f'},                           Line 153
  {"starting-line-number", required_argument, NULL, 'v'},                       Line 154
  {"line-increment", required_argument, NULL, 'i'},                             Line 155
  {"no-renumber", no_argument, NULL, 'p'},                                      Line 156
  {"join-blank-lines", required_argument, NULL, 'l'},                           Line 157
  {"number-separator", required_argument, NULL, 's'},                           Line 158
  {"number-width", required_argument, NULL, 'w'},                               Line 159
  {"number-format", required_argument, NULL, 'n'},                              Line 160
  {"section-delimiter", required_argument, NULL, 'd'},                          Line 161
  {GETOPT_HELP_OPTION_DECL},                                                    Line 162
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 163
  {NULL, 0, NULL, 0}                                                            Line 164
};                                                                              Block 2
                                                                                
/* Print a usage message and quit. */                                           
                                                                                
void                                                                            Line 169
usage (int status)                                                              Line 170
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 172
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 174
    {                                                                           
      printf (_("\                                                              Line 176
Usage: %s [OPTION]... [FILE]...\n\                                              Line 177
"),                                                                             Line 178
              program_name);                                                    Line 179
      fputs (_("\                                                               Line 180
Write each FILE to standard output, with line numbers added.\n\                 Line 181
"), stdout);                                                                    Line 182
                                                                                
      emit_stdin_note ();                                                       ...!common auto-comment...
      emit_mandatory_arg_note ();                                               ...!common auto-comment...
                                                                                
      fputs (_("\                                                               Line 187
  -b, --body-numbering=STYLE      use STYLE for numbering body lines\n\         Line 188
  -d, --section-delimiter=CC      use CC for logical page delimiters\n\         Line 189
  -f, --footer-numbering=STYLE    use STYLE for numbering footer lines\n\       Line 190
"), stdout);                                                                    Line 191
      fputs (_("\                                                               Line 192
  -h, --header-numbering=STYLE    use STYLE for numbering header lines\n\       Line 193
  -i, --line-increment=NUMBER     line number increment at each line\n\         Line 194
  -l, --join-blank-lines=NUMBER   group of NUMBER empty lines counted as one\n\ Line 195
  -n, --number-format=FORMAT      insert line numbers according to FORMAT\n\    Line 196
  -p, --no-renumber               do not reset line numbers for each section\n\ Line 197
  -s, --number-separator=STRING   add STRING after (possible) line number\n\    Line 198
"), stdout);                                                                    Line 199
      fputs (_("\                                                               Line 200
  -v, --starting-line-number=NUMBER  first line number for each section\n\      Line 201
  -w, --number-width=NUMBER       use NUMBER columns for line numbers\n\        Line 202
"), stdout);                                                                    Line 203
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 204
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 205
      fputs (_("\                                                               Line 206
\n\                                                                             
Default options are: -bt -d'\\:' -fn -hn -i1 -l1 -n'rn' -s<TAB> -v1 -w6\n\      Line 208
\n\                                                                             
CC are two delimiter characters used to construct logical page delimiters;\n\   Line 210
a missing second character implies ':'.\n\                                      Line 211
"), stdout);                                                                    Line 212
      fputs (_("\                                                               Line 213
\n\                                                                             
STYLE is one of:\n\                                                             Line 215
\n\                                                                             
  a      number all lines\n\                                                    Line 217
  t      number only nonempty lines\n\                                          Line 218
  n      number no lines\n\                                                     Line 219
  pBRE   number only lines that contain a match for the basic regular\n\        Line 220
         expression, BRE\n\                                                     Line 221
"), stdout);                                                                    Line 222
      fputs (_("\                                                               Line 223
\n\                                                                             
FORMAT is one of:\n\                                                            Line 225
\n\                                                                             
  ln     left justified, no leading zeros\n\                                    Line 227
  rn     right justified, no leading zeros\n\                                   Line 228
  rz     right justified, leading zeros\n\                                      Line 229
\n\                                                                             
"), stdout);                                                                    Line 231
      emit_ancillary_info (PROGRAM_NAME);                                       Line 232
    }                                                                           
  exit (status);                                                                Line 234
}                                                                               Block 3
                                                                                
/* Set the command line flag TYPEP and possibly the regex pointer REGEXP,       
   according to 'optarg'.  */                                                   
                                                                                
static bool                                                                     Line 240
build_type_arg (char const **typep,                                             Line 241
                struct re_pattern_buffer *regexp, char *fastmap)                Line 242
{                                                                               
  char const *errmsg;                                                           Line 244
  bool rval = true;                                                             Line 245
                                                                                
  switch (*optarg)                                                              Line 247
    {                                                                           
    case 'a':                                                                   Line 249
    case 't':                                                                   Line 250
    case 'n':                                                                   Line 251
      *typep = optarg;                                                          Line 252
      break;                                                                    Line 253
    case 'p':                                                                   Line 254
      *typep = optarg++;                                                        Line 255
      regexp->buffer = NULL;                                                    Line 256
      regexp->allocated = 0;                                                    Line 257
      regexp->fastmap = fastmap;                                                Line 258
      regexp->translate = NULL;                                                 Line 259
      re_syntax_options =                                                       Line 260
        RE_SYNTAX_POSIX_BASIC & ~RE_CONTEXT_INVALID_DUP & ~RE_NO_EMPTY_RANGES;  Line 261
      errmsg = re_compile_pattern (optarg, strlen (optarg), regexp);            Line 262
      if (errmsg)                                                               Line 263
        die (EXIT_FAILURE, 0, "%s", (errmsg));                                  Line 264
      break;                                                                    Line 265
    default:                                                                    Line 266
      rval = false;                                                             Line 267
      break;                                                                    Line 268
    }                                                                           
  return rval;                                                                  Line 270
}                                                                               Block 4
                                                                                
/* Print the line number and separator; increment the line number. */           
                                                                                
static void                                                                     Line 275
print_lineno (void)                                                             Line 276
{                                                                               
  intmax_t next_line_no;                                                        Line 278
                                                                                
  printf (lineno_format, lineno_width, line_no, separator_str);                 Line 280
                                                                                
  next_line_no = line_no + page_incr;                                           Line 282
  if (next_line_no < line_no)                                                   Line 283
    die (EXIT_FAILURE, 0, _("line number overflow"));                           Line 284
  line_no = next_line_no;                                                       Line 285
}                                                                               Block 5
                                                                                
/* Switch to a header section. */                                               
                                                                                
static void                                                                     Line 290
proc_header (void)                                                              Line 291
{                                                                               
  current_type = header_type;                                                   Line 293
  current_regex = &header_regex;                                                Line 294
  if (reset_numbers)                                                            Line 295
    line_no = starting_line_number;                                             Line 296
  putchar ('\n');                                                               Line 297
}                                                                               Block 6
                                                                                
/* Switch to a body section. */                                                 
                                                                                
static void                                                                     Line 302
proc_body (void)                                                                Line 303
{                                                                               
  current_type = body_type;                                                     Line 305
  current_regex = &body_regex;                                                  Line 306
  if (reset_numbers)                                                            Line 307
    line_no = starting_line_number;                                             Line 308
  putchar ('\n');                                                               Line 309
}                                                                               Block 7
                                                                                
/* Switch to a footer section. */                                               
                                                                                
static void                                                                     Line 314
proc_footer (void)                                                              Line 315
{                                                                               
  current_type = footer_type;                                                   Line 317
  current_regex = &footer_regex;                                                Line 318
  if (reset_numbers)                                                            Line 319
    line_no = starting_line_number;                                             Line 320
  putchar ('\n');                                                               Line 321
}                                                                               Block 8
                                                                                
/* Process a regular text line in 'line_buf'. */                                
                                                                                
static void                                                                     Line 326
proc_text (void)                                                                Line 327
{                                                                               
  static intmax_t blank_lines = 0; /* Consecutive blank lines so far. */        Line 329
                                                                                
  switch (*current_type)                                                        Line 331
    {                                                                           
    case 'a':                                                                   Line 333
      if (blank_join > 1)                                                       Line 334
        {                                                                       
          if (1 < line_buf.length || ++blank_lines == blank_join)               Line 336
            {                                                                   
              print_lineno ();                                                  Line 338
              blank_lines = 0;                                                  Line 339
            }                                                                   
          else                                                                  Line 341
            fputs (print_no_line_fmt, stdout);                                  Line 342
        }                                                                       
      else                                                                      Line 344
        print_lineno ();                                                        Line 345
      break;                                                                    Line 346
    case 't':                                                                   Line 347
      if (1 < line_buf.length)                                                  Line 348
        print_lineno ();                                                        Line 349
      else                                                                      Line 350
        fputs (print_no_line_fmt, stdout);                                      Line 351
      break;                                                                    Line 352
    case 'n':                                                                   Line 353
      fputs (print_no_line_fmt, stdout);                                        Line 354
      break;                                                                    Line 355
    case 'p':                                                                   Line 356
      switch (re_search (current_regex, line_buf.buffer, line_buf.length - 1,   Line 357
                         0, line_buf.length - 1, NULL))                         Line 358
        {                                                                       
        case -2:                                                                Line 360
          die (EXIT_FAILURE, errno, _("error in regular expression search"));   Line 361
                                                                                
        case -1:                                                                Line 363
          fputs (print_no_line_fmt, stdout);                                    Line 364
          break;                                                                Line 365
                                                                                
        default:                                                                Line 367
          print_lineno ();                                                      Line 368
          break;                                                                Line 369
        }                                                                       
    }                                                                           
  fwrite (line_buf.buffer, sizeof (char), line_buf.length, stdout);             Line 372...!syscalls auto-comment...
}                                                                               Block 9
                                                                                
/* Return the type of line in 'line_buf'. */                                    
                                                                                
static enum section                                                             Line 377
check_section (void)                                                            Line 378
{                                                                               
  size_t len = line_buf.length - 1;                                             Line 380
                                                                                
  if (len < 2 || memcmp (line_buf.buffer, section_del, 2))                      Line 382
    return Text;                                                                Line 383
  if (len == header_del_len                                                     Line 384
      && !memcmp (line_buf.buffer, header_del, header_del_len))                 Line 385
    return Header;                                                              Line 386
  if (len == body_del_len                                                       Line 387
      && !memcmp (line_buf.buffer, body_del, body_del_len))                     Line 388
    return Body;                                                                Line 389
  if (len == footer_del_len                                                     Line 390
      && !memcmp (line_buf.buffer, footer_del, footer_del_len))                 Line 391
    return Footer;                                                              Line 392
  return Text;                                                                  Line 393
}                                                                               Block 10
                                                                                
/* Read and process the file pointed to by FP. */                               
                                                                                
static void                                                                     Line 398
process_file (FILE *fp)                                                         Line 399
{                                                                               
  while (readlinebuffer (&line_buf, fp))                                        Line 401
    {                                                                           
      switch (check_section ())                                                 Line 403
        {                                                                       
        case Header:                                                            Line 405
          proc_header ();                                                       Line 406
          break;                                                                Line 407
        case Body:                                                              Line 408
          proc_body ();                                                         Line 409
          break;                                                                Line 410
        case Footer:                                                            Line 411
          proc_footer ();                                                       Line 412
          break;                                                                Line 413
        case Text:                                                              Line 414
          proc_text ();                                                         Line 415
          break;                                                                Line 416
        }                                                                       
    }                                                                           
}                                                                               Block 11
                                                                                
/* Process file FILE to standard output.                                        
   Return true if successful.  */                                               
                                                                                
static bool                                                                     Line 424
nl_file (char const *file)                                                      Line 425
{                                                                               
  FILE *stream;                                                                 Line 427
                                                                                
  if (STREQ (file, "-"))                                                        Line 429
    {                                                                           
      have_read_stdin = true;                                                   Line 431
      stream = stdin;                                                           Line 432
    }                                                                           
  else                                                                          Line 434
    {                                                                           
      stream = fopen (file, "r");                                               Line 436...!syscalls auto-comment...
      if (stream == NULL)                                                       Line 437
        {                                                                       
          error (0, errno, "%s", quotef (file));                                Line 439
          return false;                                                         Line 440
        }                                                                       
    }                                                                           
                                                                                
  fadvise (stream, FADVISE_SEQUENTIAL);                                         Line 444...!syscalls auto-comment...
                                                                                
  process_file (stream);                                                        Line 446
                                                                                
  if (ferror (stream))                                                          Line 448
    {                                                                           
      error (0, errno, "%s", quotef (file));                                    Line 450
      return false;                                                             Line 451
    }                                                                           
  if (STREQ (file, "-"))                                                        Line 453
    clearerr (stream);  /* Also clear EOF. */                                   Line 454
  else if (fclose (stream) == EOF)                                              Line 455...!syscalls auto-comment...
    {                                                                           
      error (0, errno, "%s", quotef (file));                                    Line 457
      return false;                                                             Line 458
    }                                                                           
  return true;                                                                  Line 460
}                                                                               Block 12
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 464
{                                                                               
  int c;                                                                        Line 466
  size_t len;                                                                   Line 467
  bool ok = true;                                                               Line 468
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  setlocale (LC_ALL, "");                                                       Sets up internationalization (i18n)
  bindtextdomain (PACKAGE, LOCALEDIR);                                          Assigns i18n directorySets text domain for _() [gettext()] function
  textdomain (PACKAGE);                                                         Sets text domain for _() [gettext()] function
                                                                                
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  have_read_stdin = false;                                                      Line 478
                                                                                
  while ((c = getopt_long (argc, argv, "h:b:f:v:i:pl:s:w:n:d:", longopts,       Line 480
                           NULL)) != -1)                                        Line 481
    {                                                                           
      switch (c)                                                                Line 483
        {                                                                       
        case 'h':                                                               Line 485
          if (! build_type_arg (&header_type, &header_regex, header_fastmap))   Line 486
            {                                                                   
              error (0, 0, _("invalid header numbering style: %s"),             Line 488
                     quote (optarg));                                           Line 489
              ok = false;                                                       Line 490
            }                                                                   
          break;                                                                Line 492
        case 'b':                                                               Line 493
          if (! build_type_arg (&body_type, &body_regex, body_fastmap))         Line 494
            {                                                                   
              error (0, 0, _("invalid body numbering style: %s"),               Line 496
                     quote (optarg));                                           Line 497
              ok = false;                                                       Line 498
            }                                                                   
          break;                                                                Line 500
        case 'f':                                                               Line 501
          if (! build_type_arg (&footer_type, &footer_regex, footer_fastmap))   Line 502
            {                                                                   
              error (0, 0, _("invalid footer numbering style: %s"),             Line 504
                     quote (optarg));                                           Line 505
              ok = false;                                                       Line 506
            }                                                                   
          break;                                                                Line 508
        case 'v':                                                               Line 509
          starting_line_number = xdectoimax (optarg, INTMAX_MIN, INTMAX_MAX, "",Line 510
                                             _("invalid starting line number"), Line 511
                                             0);                                
          break;                                                                Line 513
        case 'i':                                                               Line 514
          page_incr = xdectoimax (optarg, 1, INTMAX_MAX, "",                    Line 515
                                  _("invalid line number increment"), 0);       Line 516
          break;                                                                Line 517
        case 'p':                                                               Line 518
          reset_numbers = false;                                                Line 519
          break;                                                                Line 520
        case 'l':                                                               Line 521
          blank_join = xdectoimax (optarg, 1, INTMAX_MAX, "",                   Line 522
                                   _("invalid line number of blank lines"), 0); Line 523
          break;                                                                Line 524
        case 's':                                                               Line 525
          separator_str = optarg;                                               Line 526
          break;                                                                Line 527
        case 'w':                                                               Line 528
          lineno_width = xdectoimax (optarg, 1, INT_MAX, "",                    Line 529
                                     _("invalid line number field width"), 0);  Line 530
          break;                                                                Line 531
        case 'n':                                                               Line 532
          if (STREQ (optarg, "ln"))                                             Line 533
            lineno_format = FORMAT_LEFT;                                        Line 534
          else if (STREQ (optarg, "rn"))                                        Line 535
            lineno_format = FORMAT_RIGHT_NOLZ;                                  Line 536
          else if (STREQ (optarg, "rz"))                                        Line 537
            lineno_format = FORMAT_RIGHT_LZ;                                    Line 538
          else                                                                  Line 539
            {                                                                   
              error (0, 0, _("invalid line numbering format: %s"),              Line 541
                     quote (optarg));                                           Line 542
              ok = false;                                                       Line 543
            }                                                                   
          break;                                                                Line 545
        case 'd':                                                               Line 546
          section_del = optarg;                                                 Line 547
          break;                                                                Line 548
        case_GETOPT_HELP_CHAR;                                                  Line 549
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                       Line 550
        default:                                                                Line 551
          ok = false;                                                           Line 552
          break;                                                                Line 553
        }                                                                       
    }                                                                           
                                                                                
  if (!ok)                                                                      Line 557
    usage (EXIT_FAILURE);                                                       Line 558
                                                                                
  /* Initialize the section delimiters.  */                                     
  len = strlen (section_del);                                                   Line 561
                                                                                
  header_del_len = len * 3;                                                     Line 563
  header_del = xmalloc (header_del_len + 1);                                    Line 564
  stpcpy (stpcpy (stpcpy (header_del, section_del), section_del), section_del); Line 565
                                                                                
  body_del_len = len * 2;                                                       Line 567
  body_del = xmalloc (body_del_len + 1);                                        Line 568
  stpcpy (stpcpy (body_del, section_del), section_del);                         Line 569
                                                                                
  footer_del_len = len;                                                         Line 571
  footer_del = xmalloc (footer_del_len + 1);                                    Line 572
  stpcpy (footer_del, section_del);                                             Line 573
                                                                                
  /* Initialize the input buffer.  */                                           
  initbuffer (&line_buf);                                                       Line 576
                                                                                
  /* Initialize the printf format for unnumbered lines. */                      
  len = strlen (separator_str);                                                 Line 579
  print_no_line_fmt = xmalloc (lineno_width + len + 1);                         Line 580
  memset (print_no_line_fmt, ' ', lineno_width + len);                          Line 581
  print_no_line_fmt[lineno_width + len] = '\0';                                 Line 582
                                                                                
  line_no = starting_line_number;                                               Line 584
  current_type = body_type;                                                     Line 585
  current_regex = &body_regex;                                                  Line 586
                                                                                
  /* Main processing. */                                                        
                                                                                
  if (optind == argc)                                                           Line 590
    ok = nl_file ("-");                                                         Line 591
  else                                                                          Line 592
    for (; optind < argc; optind++)                                             Line 593
      ok &= nl_file (argv[optind]);                                             Line 594
                                                                                
  if (have_read_stdin && fclose (stdin) == EOF)                                 Line 596...!syscalls auto-comment...
    die (EXIT_FAILURE, errno, "-");                                             Line 597
                                                                                
  return ok ? EXIT_SUCCESS : EXIT_FAILURE;                                      Line 599
}                                                                               Block 13