Module Name:    src
Committed By:   christos
Date:           Thu May 19 22:55:54 UTC 2011

Modified Files:
        src/usr.bin/error: error.1 error.h main.c touch.c

Log Message:
- use getopt
- use err
- add -p <filelevel> to chop levels like patch
- document all the options


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/usr.bin/error/error.1
cvs rdiff -u -r1.15 -r1.16 src/usr.bin/error/error.h
cvs rdiff -u -r1.17 -r1.18 src/usr.bin/error/main.c
cvs rdiff -u -r1.22 -r1.23 src/usr.bin/error/touch.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/error/error.1
diff -u src/usr.bin/error/error.1:1.14 src/usr.bin/error/error.1:1.15
--- src/usr.bin/error/error.1:1.14	Mon Apr  5 17:18:20 2010
+++ src/usr.bin/error/error.1	Thu May 19 18:55:53 2011
@@ -1,4 +1,4 @@
-.\"	$NetBSD: error.1,v 1.14 2010/04/05 21:18:20 joerg Exp $
+.\"	$NetBSD: error.1,v 1.15 2011/05/19 22:55:53 christos Exp $
 .\"
 .\" Copyright (c) 1980, 1990, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"	@(#)error.1	8.1 (Berkeley) 6/6/93
 .\"
-.Dd June 6, 1993
+.Dd May 19, 2011
 .Dt ERROR 1
 .Os
 .Sh NAME
@@ -37,12 +37,15 @@
 .Nd analyze and disperse compiler error messages
 .Sh SYNOPSIS
 .Nm
+.Op Fl I Ar ignorefile
 .Op Fl n
-.Op Fl s
+.Pp Fl p Ar filelevel
 .Op Fl q
-.Op Fl v
+.Op Fl S
+.Op Fl s
+.Op Fl T
 .Op Fl t Ar suffixlist
-.Op Fl I Ar ignorefile
+.Op Fl v
 .Op name
 .Sh DESCRIPTION
 .Nm
@@ -83,6 +86,8 @@
 or
 .Xr \&ed 1
 from standard places.
+.It Fl T
+Terse output.
 .It Fl t
 Take the following argument as a suffix list.
 Files whose suffixes do not appear in the suffix list are not touched.
@@ -94,6 +99,12 @@
 allows
 .Nm
 to touch files ending with ``.c'', ``.y'', ``.foo*'' and ``.h''.
+.It Fl p Ar filelevel
+Interpret filenumber as a level of path component names to skip,
+similar to 
+.Xr patch 1 .
+.It Fl S
+Show the errors in unsorted order (as they come from the error file).
 .It Fl s
 Print out
 .Em statistics

Index: src/usr.bin/error/error.h
diff -u src/usr.bin/error/error.h:1.15 src/usr.bin/error/error.h:1.16
--- src/usr.bin/error/error.h:1.15	Thu Aug 13 02:59:37 2009
+++ src/usr.bin/error/error.h	Thu May 19 18:55:53 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: error.h,v 1.15 2009/08/13 06:59:37 dholland Exp $	*/
+/*	$NetBSD: error.h,v 1.16 2011/05/19 22:55:53 christos Exp $	*/
 
 /*
  * Copyright (c) 1980, 1993
@@ -88,6 +88,8 @@
 extern const char *class_table[];
 extern int class_count[];
 
+extern size_t filelevel;
+
 #define nunknown	class_count[C_UNKNOWN]
 #define nignore		class_count[C_IGNORE]
 #define nsyncerrors	class_count[C_SYNC]

Index: src/usr.bin/error/main.c
diff -u src/usr.bin/error/main.c:1.17 src/usr.bin/error/main.c:1.18
--- src/usr.bin/error/main.c:1.17	Thu Aug 13 02:59:37 2009
+++ src/usr.bin/error/main.c	Thu May 19 18:55:53 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.17 2009/08/13 06:59:37 dholland Exp $	*/
+/*	$NetBSD: main.c,v 1.18 2011/05/19 22:55:53 christos Exp $	*/
 
 /*
  * Copyright (c) 1980, 1993
@@ -39,7 +39,7 @@
 #if 0
 static char sccsid[] = "@(#)main.c	8.1 (Berkeley) 6/6/93";
 #endif
-__RCSID("$NetBSD: main.c,v 1.17 2009/08/13 06:59:37 dholland Exp $");
+__RCSID("$NetBSD: main.c,v 1.18 2011/05/19 22:55:53 christos Exp $");
 #endif /* not lint */
 
 #include <signal.h>
@@ -48,6 +48,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
+#include <err.h>
 #include "error.h"
 #include "pathnames.h"
 
@@ -57,6 +58,7 @@
 int nignored;
 char **names_ignored;
 
+size_t filelevel = 0;
 int nerrors = 0;
 Eptr er_head;
 static Eptr *errors;
@@ -81,11 +83,10 @@
 static int errorsort(const void *, const void *);
 static void forkvi(int, char **);
 static void try(const char *, int, char **);
+static void usage(void) __attribute__((__noreturn__));
 
 /*
- * error [-I ignorename] [-n] [-q] [-t suffixlist] [-s] [-v] [infile]
- *
- *	-T:	terse output
+ * error [-nqSsTv] [-I <ignorename>] [-t <suffixlist>] [-p <level>] <infile>
  *
  *	-I:	the following name, `ignorename' contains a list of
  *		function names that are not to be treated as hard errors.
@@ -93,42 +94,38 @@
  *
  *	-n:	don't touch ANY files!
  *
+ *	-p:	take the next argument as the number of levels to skip
+ *		from the filename, like perl.
+ *
  *	-q:	The user is to be queried before touching each
  *		file; if not specified, all files with hard, non
  *		ignorable errors are touched (assuming they can be).
  *
+ *	-S:	show the errors in unsorted order
+ *		(as they come from the error file)
+ *
+ *	-s:	print a summary of the error's categories.
+ *
+ *	-T:	terse output
+ *
  *	-t:	touch only files ending with the list of suffixes, each
  *		suffix preceded by a dot.
  *		eg, -t .c.y.l
  *		will touch only files ending with .c, .y or .l
  *
- *	-s:	print a summary of the error's categories.
- *
  *	-v:	after touching all files, overlay vi(1), ex(1) or ed(1)
  *		on top of error, entered in the first file with
  *		an error in it, with the appropriate editor
  *		set up to use the "next" command to get the other
  *		files containing errors.
  *
- *	-p:	(obsolete: for older versions of pi without bug
- *		fix regarding printing out the name of the main file
- *		with an error in it)
- *		Take the following argument and use it as the name of
- *		the pascal source file, suffix .p
- *
- *	-E:	show the errors in sorted order; intended for
- *		debugging.
- *
- *	-S:	show the errors in unsorted order
- *		(as they come from the error file)
- *
  *	infile:	The error messages come from this file.
  *		Default: stdin
  */
 int
 main(int argc, char **argv)
 {
-	char *cp;
+	int c;
 	char *ignorename = 0;
 	int ed_argc;
 	char **ed_argv;		/* return from touchfiles */
@@ -137,60 +134,55 @@
 	boolean pr_summary = false;
 	boolean edit_files = false;
 
-	processname = argv[0];
+	setprogname(argv[0]);
 
 	errorfile = stdin;
-	if (argc > 1)
-		for (; argc > 1 && argv[1][0] == '-'; argc--, argv++) {
-			for (cp = argv[1] + 1; *cp; cp++)
-				switch (*cp) {
-				default:
-					fprintf(stderr, "%s: -%c: Unknown flag\n",
-						processname, *cp);
-					break;
-
-				case 'n': notouch = true; break;
-				case 'q': query = true; break;
-				case 'S': Show_Errors = true; break;
-				case 's': pr_summary = true; break;
-				case 'v': edit_files = true; break;
-				case 'T': terse = true; break;
-				case 't':
-					*cp-- = 0; argv++; argc--;
-					if (argc > 1) {
-						suffixlist = argv[1];
-					}
-					break;
-				case 'I':	/*ignore file name*/
-					*cp-- = 0;
-					argv++;
-					argc--;
-					if (argc > 1)
-						ignorename = argv[1];
-					break;
-				}
+	while ((c = getopt(argc, argv, "I:np:qSsTt:v")) != -1)
+		switch (c) {
+		case 'I':	/*ignore file name*/
+			ignorename = optarg;
+			break;
+		case 'n':
+			notouch = true;
+			break;
+		case 'p':
+			filelevel = (size_t)strtol(optarg, NULL, 0);
+			break;
+		case 'q':
+			query = true;
+			break;
+		case 'S':
+			Show_Errors = true;
+			break;
+		case 's':
+			pr_summary = true;
+			break;
+		case 'T':
+			terse = true;
+			break;
+		case 't':
+			suffixlist = optarg;
+			break;
+		case 'v':
+			edit_files = true;
+			break;
+		default:
+			usage();
 		}
+
+	argv += optind;
+	argc -= optind;
 	if (notouch)
 		suffixlist = 0;
 	if (argc > 1) {
-		if (argc > 3) {
-			fprintf(stderr, "%s: Only takes 0 or 1 arguments\n",
-				processname);
-			exit(3);
-		}
-		if ((errorfile = fopen(argv[1], "r")) == NULL) {
-			fprintf(stderr, "%s: %s: No such file or directory for reading errors.\n",
-				processname, argv[1]);
-			exit(4);
-		}
+		if (argc > 3)
+			usage();
+		if ((errorfile = fopen(argv[1], "r")) == NULL)
+			err(1, "Cannot open `%s' to read errors", argv[1]);
 	}
 	if ((queryfile = fopen(im_on, "r")) == NULL) {
-		if (query) {
-			fprintf(stderr,
-				"%s: Can't open \"%s\" to query the user.\n",
-				processname, im_on);
-			exit(9);
-		}
+		if (query)
+			err(1, "Cannot open `%s' to query the user", im_on);
 	}
 	if (signal(SIGINT, onintr) == SIG_IGN)
 		signal(SIGINT, SIG_IGN);
@@ -301,3 +293,11 @@
 	}
 	return (order);
 }
+
+static void
+usage(void)
+{
+	fprintf(stderr, "Usage: %s [-nqSsTv] [-I <ignorename>] "
+	    "[-t <suffixlist>] [-p <level>] <infile>\n", getprogname());
+	exit(1);
+}

Index: src/usr.bin/error/touch.c
diff -u src/usr.bin/error/touch.c:1.22 src/usr.bin/error/touch.c:1.23
--- src/usr.bin/error/touch.c:1.22	Thu Aug 13 02:59:37 2009
+++ src/usr.bin/error/touch.c	Thu May 19 18:55:53 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: touch.c,v 1.22 2009/08/13 06:59:37 dholland Exp $	*/
+/*	$NetBSD: touch.c,v 1.23 2011/05/19 22:55:53 christos Exp $	*/
 
 /*
  * Copyright (c) 1980, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)touch.c	8.1 (Berkeley) 6/6/93";
 #endif
-__RCSID("$NetBSD: touch.c,v 1.22 2009/08/13 06:59:37 dholland Exp $");
+__RCSID("$NetBSD: touch.c,v 1.23 2011/05/19 22:55:53 christos Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -87,12 +87,30 @@
 static void errorprint(FILE *, Eptr, boolean);
 static int probethisfile(const char *);
 
+static const char *
+makename(const char *name, size_t level)
+{
+	const char *p;
+
+	if (level-- == 0)
+		return name;
+
+	if (*name == '/') {
+		name++;
+		if (level-- == 0)
+			return name;
+	}
+
+	while (level-- != 0 && (p = strchr(name, '/')) != NULL)
+		name = p + 1;
+
+	return name;
+}
 void
 findfiles(int my_nerrors, Eptr *my_errors, int *r_nfiles, Eptr ***r_files)
 {
 	int my_nfiles;
 	Eptr **my_files;
-
 	const char *name;
 	int ei;
 	int fi;
@@ -122,10 +140,11 @@
 	name = "\1";
 	fi = 1;
 	ECITERATE(ei, errorp, ei, my_errors, my_nerrors) {
+		const char *fname = makename(errorp->error_text[0], filelevel);
 		if (errorp->error_e_class == C_NULLED
 		    || errorp->error_e_class == C_TRUE) {
-			if (strcmp(errorp->error_text[0], name) != 0) {
-				name = errorp->error_text[0];
+			if (strcmp(fname, name) != 0) {
+				name = fname;
 				touchedfiles[fi] = false;
 				my_files[fi] = &my_errors[ei];
 				fi++;
@@ -149,9 +168,11 @@
 	name = "\1";
 	ECITERATE(ei, errorp, 0, errors, nerrors) {
 		if (SORTABLE(errorp->error_e_class)) {
-			if (strcmp(errorp->error_text[0],name) != 0) {
+			const char *fname = makename(errorp->error_text[0],
+			    filelevel);
+			if (strcmp(fname, name) != 0) {
 				my_nfiles++;
-				name = errorp->error_text[0];
+				name = name;
 			}
 		}
 	}
@@ -195,7 +216,9 @@
 		if (!terse) {
 			FILEITERATE(fi, 1, my_nfiles) {
 				fprintf(stdout, "%s\"%s\" (%d)",
-					sep, (*my_files[fi])->error_text[0],
+					sep, makename(
+					(*my_files[fi])->error_text[0],
+					filelevel),
 					(int)(my_files[fi+1] - my_files[fi]));
 				sep = ", ";
 			}
@@ -241,6 +264,7 @@
 	return (someerrors);
 }
 
+
 bool
 touchfiles(int my_nfiles, Eptr **my_files, int *r_edargc, char ***r_edargv)
 {
@@ -254,8 +278,9 @@
 	int spread;
 
 	FILEITERATE(fi, 1, my_nfiles) {
-		name = (*my_files[fi])->error_text[0];
+		name = makename((*my_files[fi])->error_text[0], filelevel);
 		spread = my_files[fi+1] - my_files[fi];
+
 		fprintf(stdout, terse
 			? "\"%s\" has %d error%s, "
 			: "\nFile \"%s\" has %d error%s.\n"
@@ -501,7 +526,7 @@
 execvarg(int n_pissed_on, int *r_argc, char ***r_argv)
 {
 	Eptr p;
-	const char *sep;
+	const char *sep, *name;
 	int fi;
 
 	sep = NULL;
@@ -517,11 +542,12 @@
 		if (!touchedfiles[fi])
 			continue;
 		p = *(files[fi]);
+		name = makename(p->error_text[0], filelevel);
 		if (!terse) {
-			fprintf(stdout,"%s\"%s\"", sep, p->error_text[0]);
+			fprintf(stdout,"%s\"%s\"", sep, name);
 			sep = ", ";
 		}
-		(*r_argv)[n_pissed_on++] = p->error_text[0];
+		(*r_argv)[n_pissed_on++] = __UNCONST(name);
 	}
 	if (!terse)
 		fprintf(stdout, "\n");

Reply via email to