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 that match 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