- use getopt
- use err - add -p <filelevel> to chop levels like patch - document all the options
This commit is contained in:
parent
aabb34a38b
commit
ec9611ac0f
|
@ -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 n
|
||||
.Op Fl s
|
||||
.Op Fl q
|
||||
.Op Fl v
|
||||
.Op Fl t Ar suffixlist
|
||||
.Op Fl I Ar ignorefile
|
||||
.Op Fl n
|
||||
.Pp Fl p Ar filelevel
|
||||
.Op Fl q
|
||||
.Op Fl S
|
||||
.Op Fl s
|
||||
.Op Fl T
|
||||
.Op Fl t Ar suffixlist
|
||||
.Op Fl v
|
||||
.Op name
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
|
@ -83,6 +86,8 @@ can't be found, try
|
|||
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 @@ Thus the suffix list:
|
|||
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
|
||||
|
|
|
@ -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 @@ typedef int Errorclass;
|
|||
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]
|
||||
|
|
|
@ -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 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1993\
|
|||
#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 @@ __RCSID("$NetBSD: main.c,v 1.17 2009/08/13 06:59:37 dholland Exp $");
|
|||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include "error.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
|
@ -57,6 +58,7 @@ FILE *queryfile; /* where the query responses from the user come from*/
|
|||
int nignored;
|
||||
char **names_ignored;
|
||||
|
||||
size_t filelevel = 0;
|
||||
int nerrors = 0;
|
||||
Eptr er_head;
|
||||
static Eptr *errors;
|
||||
|
@ -81,11 +83,10 @@ const char *suffixlist = ".*"; /* initially, can touch any file */
|
|||
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 @@ static void try(const char *, int, char **);
|
|||
*
|
||||
* -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 @@ main(int argc, char **argv)
|
|||
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 @@ errorsort(const void *x1, const void *x2)
|
|||
}
|
||||
return (order);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-nqSsTv] [-I <ignorename>] "
|
||||
"[-t <suffixlist>] [-p <level>] <infile>\n", getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -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 int mustwrite(const char *, unsigned, FILE *);
|
|||
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 @@ findfiles(int my_nerrors, Eptr *my_errors, int *r_nfiles, Eptr ***r_files)
|
|||
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 @@ countfiles(Eptr *errors)
|
|||
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 @@ filenames(int my_nfiles, Eptr **my_files)
|
|||
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 @@ nopertain(Eptr **my_files)
|
|||
return (someerrors);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
touchfiles(int my_nfiles, Eptr **my_files, int *r_edargc, char ***r_edargv)
|
||||
{
|
||||
|
@ -254,8 +278,9 @@ touchfiles(int my_nfiles, Eptr **my_files, int *r_edargc, char ***r_edargv)
|
|||
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 @@ static void
|
|||
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 @@ execvarg(int n_pissed_on, int *r_argc, char ***r_argv)
|
|||
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");
|
||||
|
|
Loading…
Reference in New Issue