nl.c (1391B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <regex.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <unistd.h> 7 8 #include "text.h" 9 #include "util.h" 10 11 static void nl(const char *, FILE *); 12 13 static char mode = 't'; 14 static const char *sep = "\t"; 15 static long incr = 1; 16 static regex_t preg; 17 18 static void 19 usage(void) 20 { 21 eprintf("usage: %s [-b type] [-i incr] [-s sep] [file]\n", argv0); 22 } 23 24 int 25 main(int argc, char *argv[]) 26 { 27 FILE *fp; 28 char *r; 29 30 ARGBEGIN { 31 case 'b': 32 r = EARGF(usage()); 33 mode = r[0]; 34 if (r[0] == 'p') 35 eregcomp(&preg, &r[1], REG_NOSUB); 36 else if (!strchr("ant", mode)) 37 usage(); 38 break; 39 case 'i': 40 incr = estrtol(EARGF(usage()), 0); 41 break; 42 case 's': 43 sep = EARGF(usage()); 44 break; 45 default: 46 usage(); 47 } ARGEND; 48 49 if (argc > 1) 50 usage(); 51 52 if (argc == 0) { 53 nl("<stdin>", stdin); 54 } else { 55 if (!(fp = fopen(argv[0], "r"))) 56 eprintf("fopen %s:", argv[0]); 57 nl(argv[0], fp); 58 fclose(fp); 59 } 60 return 0; 61 } 62 63 void 64 nl(const char *name, FILE *fp) 65 { 66 char *buf = NULL; 67 long n = 0; 68 size_t size = 0; 69 70 while (getline(&buf, &size, fp) != -1) { 71 if ((mode == 'a') 72 || (mode == 'p' && !regexec(&preg, buf, 0, NULL, 0)) 73 || (mode == 't' && buf[0] != '\n')) 74 printf("%6ld%s%s", n += incr, sep, buf); 75 else 76 printf(" %s", buf); 77 } 78 free(buf); 79 if (ferror(fp)) 80 eprintf("%s: read error:", name); 81 }