busybox/coreutils/nl.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com>
   4 *
   5 * Licensed under GPLv2, see file LICENSE in this source tree.
   6 */
   7//config:config NL
   8//config:       bool "nl (4.6 kb)"
   9//config:       default y
  10//config:       help
  11//config:       nl is used to number lines of files.
  12
  13//applet:IF_NL(APPLET(nl, BB_DIR_USR_BIN, BB_SUID_DROP))
  14
  15//kbuild:lib-$(CONFIG_NL) += nl.o
  16
  17//usage:#define nl_trivial_usage
  18//usage:       "[OPTIONS] [FILE]..."
  19//usage:#define nl_full_usage "\n\n"
  20//usage:       "Write FILEs to standard output with line numbers added\n"
  21//usage:     "\n        -b STYLE        Which lines to number - a: all, t: nonempty, n: none"
  22//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^TODO: support "pBRE": number only lines thatmatch regexp BRE"
  23////usage:     "\n      -f STYLE        footer lines"
  24////usage:     "\n      -h STYLE        header lines"
  25////usage:     "\n      -d CC           use CC for separating logical pages"
  26//usage:     "\n        -i N            Line number increment"
  27////usage:     "\n      -l NUMBER       group of NUMBER empty lines counted as one"
  28////usage:     "\n      -n FORMAT       lneft justified, no leading zeros; rn or rz"
  29////usage:     "\n      -p              do not reset line numbers at logical pages (huh?)"
  30//usage:     "\n        -s STRING       Use STRING as line number separator"
  31//usage:     "\n        -v N            Start from N"
  32//usage:     "\n        -w N            Width of line numbers"
  33
  34/* By default, selects -v1 -i1 -l1 -sTAB -w6 -nrn -hn -bt -fn */
  35
  36#include "libbb.h"
  37
  38int nl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  39int nl_main(int argc UNUSED_PARAM, char **argv)
  40{
  41        struct number_state ns;
  42        const char *opt_b = "t";
  43        enum {
  44                OPT_p = (1 << 0),
  45        };
  46#if ENABLE_LONG_OPTS
  47        static const char nl_longopts[] ALIGN1 =
  48                "body-numbering\0"      Required_argument "b"
  49        //      "footer-numbering\0"    Required_argument "f" - not implemented yet
  50        //      "header-numbering\0"    Required_argument "h" - not implemented yet
  51        //      "section-delimiter\0"   Required_argument "d" - not implemented yet
  52                "line-increment\0"      Required_argument "i"
  53        //      "join-blank-lines\0"    Required_argument "l" - not implemented yet
  54        //      "number-format\0"       Required_argument "n" - not implemented yet
  55                "no-renumber\0"         No_argument       "p" // no-op so far
  56                "number-separator\0"    Required_argument "s"
  57                "starting-line-number\0"Required_argument "v"
  58                "number-width\0"        Required_argument "w"
  59        ;
  60#endif
  61        int exitcode;
  62
  63        ns.width = 6;
  64        ns.start = 1;
  65        ns.inc = 1;
  66        ns.sep = "\t";
  67        getopt32long(argv, "pw:+s:v:+i:+b:", nl_longopts,
  68                        &ns.width, &ns.sep, &ns.start, &ns.inc, &opt_b);
  69        ns.all = (opt_b[0] == 'a');
  70        ns.nonempty = (opt_b[0] == 't');
  71        ns.empty_str = xasprintf("%*s\n", ns.width + (int)strlen(ns.sep), "");
  72
  73        argv += optind;
  74        if (!*argv)
  75                *--argv = (char*)"-";
  76
  77        exitcode = EXIT_SUCCESS;
  78        do {
  79                exitcode |= print_numbered_lines(&ns, *argv);
  80        } while (*++argv);
  81
  82        fflush_stdout_and_exit(exitcode);
  83}
  84