4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 #pragma ident "%Z%%M% %I% %E% SMI"
43 Eptr
**files
; /* array of pointers into errors */
46 char *currentfilename
= "????";
48 char im_on
[] = "/dev/tty"; /* my tty name */
50 boolean query
= FALSE
; /* query the operator if touch files */
51 boolean notouch
= FALSE
; /* don't touch ANY files */
52 boolean terse
= FALSE
; /* Terse output */
54 char *suffixlist
= ".*"; /* initially, can touch any file */
56 static void try(char *name
, int argc
, char **argv
);
57 static void forkvi(int argc
, char **argv
);
58 static int errorsort(const void *arg1
, const void *arg2
);
62 * error [-I ignorename] [-n] [-q] [-t suffixlist] [-s] [-v] [infile]
66 * -I: the following name, `ignorename' contains a list of
67 * function names that are not to be treated as hard errors.
68 * Default: ~/.errorsrc
70 * -n: don't touch ANY files!
72 * -q: The user is to be queried before touching each
73 * file; if not specified, all files with hard, non
74 * ignorable errors are touched (assuming they can be).
76 * -t: touch only files ending with the list of suffices, each
77 * suffix preceded by a dot.
79 * will touch only files ending with .c, .y or .l
81 * -s: print a summary of the error's categories.
83 * -v: after touching all files, overlay vi(1), ex(1) or ed(1)
84 * on top of error, entered in the first file with
85 * an error in it, with the appropriate editor
86 * set up to use the "next" command to get the other
87 * files containing errors.
89 * -p: (obsolete: for older versions of pi without bug
90 * fix regarding printing out the name of the main file
91 * with an error in it)
92 * Take the following argument and use it as the name of
93 * the pascal source file, suffix .p
95 * -E: show the errors in sorted order; intended for
98 * -S: show the errors in unsorted order
99 * (as they come from the error file)
101 * infile: The error messages come from this file.
105 main(int argc
, char *argv
[])
108 char *ignorename
= 0;
110 char **ed_argv
; /* return from touchfiles */
111 boolean show_errors
= FALSE
;
112 boolean Show_Errors
= FALSE
;
113 boolean pr_summary
= FALSE
;
114 boolean edit_files
= FALSE
;
116 processname
= argv
[0];
120 for (; (argc
> 1) && (argv
[1][0] == '-'); argc
--, argv
++) {
121 for (cp
= argv
[1] + 1; *cp
; cp
++) {
124 (void) fprintf(stderr
,
125 "%s: -%c: Unknown flag\n",
151 suffixlist
= argv
[1];
154 case 'I': /* ignore file name */
159 ignorename
= argv
[1];
169 (void) fprintf(stderr
,
170 "%s: Only takes 0 or 1 arguments\n",
174 if ((errorfile
= fopen(argv
[1], "r")) == NULL
) {
175 (void) fprintf(stderr
,
176 "%s: %s: No such file or directory for "
177 "reading errors.\n", processname
, argv
[1]);
181 if ((queryfile
= fopen(im_on
, "r")) == NULL
) {
183 (void) fprintf(stderr
,
184 "%s: Can't open \"%s\" to query the user.\n",
189 if (signal(SIGINT
, onintr
) == SIG_IGN
)
190 (void) signal(SIGINT
, SIG_IGN
);
191 if (signal(SIGTERM
, onintr
) == SIG_IGN
)
192 (void) signal(SIGTERM
, SIG_IGN
);
193 getignored(ignorename
);
194 eaterrors(&nerrors
, &errors
);
196 printerrors(TRUE
, nerrors
, errors
);
197 qsort(errors
, nerrors
, sizeof (Eptr
), errorsort
);
199 printerrors(FALSE
, nerrors
, errors
);
200 findfiles(nerrors
, errors
, &nfiles
, &files
);
203 (void) fprintf(stdout
,
204 "%d Errors are unclassifiable.\n",
207 (void) fprintf(stdout
,
208 "%d Errors are classifiable, but totally "
209 "discarded.\n", nignore
);
211 (void) fprintf(stdout
,
212 "%d Errors are synchronization errors.\n",
215 (void) fprintf(stdout
,
216 "%d Errors are discarded because they "
217 "refer to sacrosanct files.\n", ndiscard
);
219 (void) fprintf(stdout
,
220 "%d Errors are nulled because they refer "
221 "to specific functions.\n", nnulled
);
223 (void) fprintf(stdout
,
224 "%d Errors are not specific to any file.\n",
227 (void) fprintf(stdout
,
228 "%d Errors are specific to a given file, "
229 "but not to a line.\n", nthisfile
);
231 (void) fprintf(stdout
,
232 "%d Errors are true errors, and can be "
233 "inserted into the files.\n", ntrue
);
235 filenames(nfiles
, files
);
236 (void) fflush(stdout
);
237 if (touchfiles(nfiles
, files
, &ed_argc
, &ed_argv
) && edit_files
)
238 forkvi(ed_argc
, ed_argv
);
243 forkvi(int argc
, char **argv
)
246 switch (inquire(terse
248 : "Do you still want to edit the files you touched? ")) {
257 * ed_agument's first argument is
258 * a vi/ex compatabile search argument
259 * to find the first occurance of ###
261 try("vi", argc
, argv
);
262 try("ex", argc
, argv
);
263 try("ed", argc
-1, argv
+1);
264 (void) fprintf(stdout
, "Can't find any editors.\n");
268 try(char *name
, int argc
, char **argv
)
271 wordvprint(stdout
, argc
, argv
);
272 (void) fprintf(stdout
, "\n");
273 (void) fflush(stderr
);
274 (void) fflush(stdout
);
276 if (freopen(im_on
, "r", stdin
) == NULL
)
278 if (freopen(im_on
, "w", stdout
) == NULL
)
280 (void) execvp(name
, argv
);
284 errorsort(const void *arg1
, const void *arg2
)
286 Eptr
*epp1
= (Eptr
*)arg1
;
287 Eptr
*epp2
= (Eptr
*)arg2
;
293 * 1) synchronization, non specific, discarded errors first;
294 * 2) nulled and true errors last
295 * a) grouped by similar file names
296 * 1) grouped in ascending line number
298 ep1
= *epp1
; ep2
= *epp2
;
299 if (ep1
== 0 || ep2
== 0)
301 if ((NOTSORTABLE(ep1
->error_e_class
)) ^
302 (NOTSORTABLE(ep2
->error_e_class
))) {
303 return (NOTSORTABLE(ep1
->error_e_class
) ? -1 : 1);
305 if (NOTSORTABLE(ep1
->error_e_class
)) /* then both are */
306 return (ep1
->error_no
- ep2
->error_no
);
307 order
= strcmp(ep1
->error_text
[0], ep2
->error_text
[0]);
309 return (ep1
->error_line
- ep2
->error_line
);