nl: add -d -p -f -h options
This commit is contained in:
		
							
								
								
									
										1
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								LICENSE
									
									
									
									
									
								
							| @@ -56,3 +56,4 @@ Authors/contributors include: | ||||
| © 2014 Adria Garriga <rhaps0dy@installgentoo.com> | ||||
| © 2014 Greg Reagle <greg.reagle@umbc.edu> | ||||
| © 2015 Tai Chi Minh Ralph Eastwood <tcmreastwood@gmail.com> | ||||
| © 2015 Quentin Rameau <quinq@quinq.eu.org> | ||||
|   | ||||
							
								
								
									
										2
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								README
									
									
									
									
									
								
							| @@ -49,7 +49,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support, | ||||
| =*| mktemp          non-posix                    none | ||||
| =*| mv              yes                          none (-i) | ||||
| =*| nice            yes                          none | ||||
| =   nl              no                           -d, -f, -h, -p | ||||
| =*  nl              yes                          none | ||||
| =*| nohup           yes                          none | ||||
| #*| paste           yes                          none | ||||
| =*| printenv        non-posix                    none | ||||
|   | ||||
							
								
								
									
										26
									
								
								nl.1
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								nl.1
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| .Dd February 20, 2015 | ||||
| .Dd March 18, 2015 | ||||
| .Dt NL 1 | ||||
| .Os sbase | ||||
| .Sh NAME | ||||
| @@ -6,7 +6,11 @@ | ||||
| .Nd line numbering filter | ||||
| .Sh SYNOPSIS | ||||
| .Nm | ||||
| .Op Fl p | ||||
| .Op Fl b Ar type | ||||
| .Op Fl d Ar delim | ||||
| .Op Fl f Ar type | ||||
| .Op Fl h Ar type | ||||
| .Op Fl i Ar incr | ||||
| .Op Fl l Ar num | ||||
| .Op Fl n Ar format | ||||
| @@ -25,8 +29,10 @@ is given | ||||
| reads from stdin. | ||||
| .Sh OPTIONS | ||||
| .Bl -tag -width Ds | ||||
| .It Fl p | ||||
| Do not reset number for logical pages | ||||
| .It Fl b Ar type | ||||
| Defines which lines will be numbered: | ||||
| Defines which lines will be numbered for body sections: | ||||
| .Bl -tag -width pstringXX | ||||
| .It a | ||||
| All lines. | ||||
| @@ -40,6 +46,16 @@ Only lines which match | ||||
| a regular expression as defined in | ||||
| .Xr regex 7 . | ||||
| .El | ||||
| .It Fl d Ar delim | ||||
| Specify the two characters delimiter (default is "\\:"). If only one character is specified, the second remains ':'. | ||||
| .It Fl f Ar type | ||||
| Same as | ||||
| .Fl b | ||||
| except for footer sections. | ||||
| .It Fl h Ar type | ||||
| Same as | ||||
| .Fl b | ||||
| except for header sections. | ||||
| .It Fl i Ar incr | ||||
| Defines the increment between numbered lines. | ||||
| .It Fl l Ar num | ||||
| @@ -76,3 +92,9 @@ The default is 6. | ||||
| .El | ||||
| .Sh SEE ALSO | ||||
| .Xr pr 1 | ||||
| .Sh STANDARDS | ||||
| The | ||||
| .Nm | ||||
| utility is compliant with the | ||||
| .St -p1003.1-2008 | ||||
| specification. | ||||
|   | ||||
							
								
								
									
										95
									
								
								nl.c
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								nl.c
									
									
									
									
									
								
							| @@ -13,29 +13,64 @@ | ||||
| #define FORMAT_RN "%*ld%s" | ||||
| #define FORMAT_RZ "%0*ld%s" | ||||
|  | ||||
| static char        mode = 't'; | ||||
| static int         blines = 1; | ||||
| static char        type[] = { 'n', 't', 'n' }; /* footer, body, header */ | ||||
| static char        delim[] = { '\\', ':' }; | ||||
| static const char *format = FORMAT_RN; | ||||
| static const char *sep = "\t"; | ||||
| static int         width = 6; | ||||
| static int         pflag = 0; | ||||
| static size_t      startnum = 1; | ||||
| static size_t      incr = 1; | ||||
| static regex_t     preg; | ||||
| static size_t      blines = 1; | ||||
| static regex_t     preg[3]; | ||||
|  | ||||
| static int | ||||
| getsection(char *buf, int *section) | ||||
| { | ||||
| 	int sectionchanged = 0; | ||||
| 	int newsection = *section; | ||||
|  | ||||
| 	while (!strncmp(buf, delim, 2)) { | ||||
| 		if (!sectionchanged) { | ||||
| 			sectionchanged = 1; | ||||
| 			newsection = 0; | ||||
| 		} else { | ||||
| 			++newsection; | ||||
| 			newsection %= 3; | ||||
| 		} | ||||
| 		buf += 2; | ||||
| 	} | ||||
|  | ||||
| 	if (buf && buf[0] == '\n') | ||||
| 		*section = newsection; | ||||
| 	else | ||||
| 		sectionchanged = 0; | ||||
|  | ||||
| 	return sectionchanged; | ||||
| } | ||||
|  | ||||
| static void | ||||
| nl(const char *name, FILE *fp) | ||||
| { | ||||
| 	char *buf = NULL; | ||||
| 	int donumber, bl = 1; | ||||
| 	size_t size = 0; | ||||
| 	int donumber, oldsection, section = 1, bl = 1; | ||||
| 	size_t number = startnum, size = 0; | ||||
|  | ||||
| 	while (getline(&buf, &size, fp) != -1) { | ||||
| 		donumber = 0; | ||||
| 		oldsection = section; | ||||
|  | ||||
| 		if ((mode == 't' && buf[0] != '\n') | ||||
| 		    || (mode == 'p' && !regexec(&preg, buf, 0, NULL, 0))) { | ||||
| 		if (getsection(buf, §ion)) { | ||||
| 			if ((section >= oldsection) && !pflag) | ||||
| 				number = startnum; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if ((type[section] == 't' && buf[0] != '\n') | ||||
| 		    || (type[section] == 'p' && | ||||
| 		        !regexec(&preg[section], buf, 0, NULL, 0))) { | ||||
| 			donumber = 1; | ||||
| 		} else if (mode == 'a') { | ||||
| 		} else if (type[section] == 'a') { | ||||
| 			if (buf[0] == '\n' && bl < blines) { | ||||
| 				++bl; | ||||
| 			} else { | ||||
| @@ -45,8 +80,8 @@ nl(const char *name, FILE *fp) | ||||
| 		} | ||||
|  | ||||
| 		if (donumber) { | ||||
| 			printf(format, width, startnum, sep); | ||||
| 			startnum += incr; | ||||
| 			printf(format, width, number, sep); | ||||
| 			number += incr; | ||||
| 		} else { | ||||
| 			printf("%*s", width, ""); | ||||
| 		} | ||||
| @@ -60,23 +95,46 @@ nl(const char *name, FILE *fp) | ||||
| static void | ||||
| usage(void) | ||||
| { | ||||
| 	eprintf("usage: %s [-b type] [-i incr] [-l num] [-n format] [-s sep] [-v startnum] [-w width] [file]\n", argv0); | ||||
| 	eprintf("usage: %s [-p] [-b type] [-d delim] [-f type] " | ||||
| 	    "[-h type] [-i incr] [-l num]\n[-n format] [-s sep] " | ||||
| 	    "[-v startnum] [-w width] [file]\n", argv0); | ||||
| } | ||||
| static char | ||||
| getlinetype(char *type, regex_t *preg) | ||||
| { | ||||
| 	if (type[0] == 'p') | ||||
| 		eregcomp(preg, &type[1], REG_NOSUB); | ||||
| 	else if (!strchr("ant", type[0])) | ||||
| 		usage(); | ||||
|  | ||||
| 	return type[0]; | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char *argv[]) | ||||
| { | ||||
| 	FILE *fp; | ||||
| 	char *r; | ||||
| 	char *d; | ||||
|  | ||||
| 	ARGBEGIN { | ||||
| 	case 'b': | ||||
| 		r = EARGF(usage()); | ||||
| 		mode = r[0]; | ||||
| 		if (r[0] == 'p') | ||||
| 			eregcomp(&preg, &r[1], REG_NOSUB); | ||||
| 		else if (!strchr("ant", mode)) | ||||
| 		type[1] = getlinetype(EARGF(usage()), &preg[1]); | ||||
| 		break; | ||||
| 	case 'd': | ||||
| 		d = EARGF(usage()); | ||||
| 		if (strlen(d) > 2) { | ||||
| 			usage(); | ||||
| 		} else if (d[0] != '\0') { | ||||
| 			delim[0] = d[0]; | ||||
| 			if (d[1]) | ||||
| 				delim[1] = d[1]; | ||||
| 		} | ||||
| 		break; | ||||
| 	case 'f': | ||||
| 		type[0] = getlinetype(EARGF(usage()), &preg[0]); | ||||
| 		break; | ||||
| 	case 'h': | ||||
| 		type[2] = getlinetype(EARGF(usage()), &preg[2]); | ||||
| 		break; | ||||
| 	case 'i': | ||||
| 		incr = estrtonum(EARGF(usage()), 0, MIN(LLONG_MAX, SIZE_MAX)); | ||||
| @@ -95,6 +153,9 @@ main(int argc, char *argv[]) | ||||
| 		else | ||||
| 			eprintf("%s: bad format\n", format); | ||||
| 		break; | ||||
| 	case 'p': | ||||
| 		pflag = 1; | ||||
| 		break; | ||||
| 	case 's': | ||||
| 		sep = EARGF(usage()); | ||||
| 		break; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user