static char *sccsid
= "@(#)errortouch.c 1.2 (Berkeley) 10/16/80";
findfiles(nerrors
, errors
, r_nfiles
, r_files
)
struct error_desc
**errors
;
struct error_desc
****r_files
;
struct error_desc
***files
;
register struct error_desc
*errorp
;
* First, go through and count all of the filenames
for (errorp
= errors
[errorindex
= 0],nfiles
= 0, currentfilename
= "\1";
errorp
= errors
[++errorindex
]){
if (SORTABLE(errorp
->error_e_class
)){
if (strcmp(errorp
->error_text
[0],currentfilename
) != 0){
currentfilename
= errorp
->error_text
[0];
files
= (struct error_desc
***)Calloc(nfiles
+ 3,
sizeof (struct error_desc
**));
touchedfiles
= (boolean
*)Calloc(nfiles
+3, sizeof(boolean
));
* Now, go through and partition off the error messages
* into those that are synchronization, discarded or
* not specific to any file, and those that were
for (errorp
= errors
[errorindex
= 0], fileindex
= 0;
(errorindex
< nerrors
) &&
(NOTSORTABLE(errorp
->error_e_class
));
errorp
= errors
[++errorindex
]){
* Now, go through and partition off all error messages
files
[1] = &errors
[errorindex
];
touchedfiles
[0] = touchedfiles
[1] = FALSE
;
for (errorp
= errors
[errorindex
], currentfilename
= "\1", fileindex
= 1;
errorindex
< nerrors
; errorp
= errors
[++errorindex
]){
if ( (errorp
->error_e_class
== C_NULLED
) || (errorp
->error_e_class
== C_TRUE
) ){
if (strcmp(errorp
->error_text
[0],currentfilename
) != 0){
currentfilename
= errorp
->error_text
[0];
touchedfiles
[fileindex
] = FALSE
;
files
[fileindex
++] = &errors
[errorindex
];
files
[fileindex
] = &errors
[nerrors
];
/*C_UNKNOWN 0 */ "Unknown",
/*C_IGNORE 1 */ "ignore",
/*C_SYNC 2 */ "synchronization",
/*C_DISCARD 3 */ "discarded",
/*C_NONSPEC 4 */ "non specific",
/*C_THISFILE 5 */ "specific to this file",
/*C_NULLED 6 */ "nulled",
/*C_DUPL 8 */ "duplicated"
int class_count
[C_LAST
- C_FIRST
] = {0};
struct error_desc
***files
;
register struct error_desc
*errorp
;
register struct error_desc
**erpp
;
extern char *class_table
[];
* first, go through and simply dump out errors that
* don't pertain to any file
if (files
[1] - files
[0] > 0){
for(errortype
= C_UNKNOWN
; NOTSORTABLE(errortype
); errortype
++){
if (class_count
[errortype
] > 0){
fprintf(stdout
, "\n\t%d %s errors follow:\n",
class_count
[errortype
], class_table
[errortype
]);
for (errorp
= *(erpp
= files
[0]);
if (errorp
->error_e_class
== errortype
)
errorprint(stdout
, errorp
, TRUE
);
fprintf(stdout
, "%d files contain errors:", nfiles
);
for (fileindex
= 1; fileindex
<= nfiles
; fileindex
++){
fprintf(stdout
, "%s\"%s\" (%d)",
sep
, (*files
[fileindex
])->error_text
[0],
files
[fileindex
+1] - files
[fileindex
]);
fprintf(stdout
, "No errors.\n");
boolean
touchfiles(nfiles
, files
, r_edargc
, r_edargv
)
struct error_desc
***files
;
register struct error_desc
*errorp
;
register struct error_desc
**erpp
;
int errordest
; /* where errors go*/
int n_pissed_on
; /* # of file touched*/
for (fileindex
= 1; fileindex
<= nfiles
; fileindex
++){
fprintf(stdout
, "\nFile \"%s\" has %d total error messages.\n",
currentfilename
= (*files
[fileindex
])->error_text
[0],
files
[fileindex
+1] - files
[fileindex
]);
* First, iterate through all error messages in this file
* to see how many of the error messages really will
* get inserted into the file.
for (erpp
= files
[fileindex
], ntrueerrors
= 0;
erpp
< files
[fileindex
+1];
if (errorp
->error_e_class
== C_TRUE
)
fprintf(stdout
,"\t%d of these errors can be inserted into the file.\n",
* What does the operator want?
if (oktotouch(currentfilename
) && (ntrueerrors
> 0) ){
if (query
&& inquire("Do you want to preview the errors first?")){
for (erpp
= files
[fileindex
];
erpp
< files
[fileindex
+ 1];
errorprint(stdout
, *erpp
, TRUE
);
|| inquire("Do you want to touch file \"%s\"? ",
if (!probethisfile(currentfilename
)){
"Can't find file \"%s\" to insert error messages into.\n",
if (edit(currentfilename
))
touchedfiles
[fileindex
] = TRUE
;
if (previewed
&& (errordest
== TOSTDOUT
))
continue; /* with the next file */
* go through and print each error message,
* diverting to the right place
if ( (files
[fileindex
+1] - files
[fileindex
]) != ntrueerrors
)
if (!previewed
) fprintf(stdout
,
">>Uninserted error messages for file \"%s\" follow.\n",
for (erpp
= files
[fileindex
];erpp
< files
[fileindex
+1];erpp
++){
if (errorp
->error_e_class
== C_TRUE
){
errorprint(stdout
,errorp
, TRUE
);
insert(errorp
->error_line
);
errorprint(stdout
, errorp
, TRUE
);
} /* end of walking through all errors*/
if (errordest
== TOTHEFILE
){
} /* end of walking through all files*/
for (n_pissed_on
= 0, fileindex
= 1; fileindex
<= nfiles
; fileindex
++){
scribbled
|= touchedfiles
[fileindex
];
* Construct an execv argument
* We need 1 argument for the editor's name
* We need 1 argument for the initial search string
* We need n_pissed_on arguments for the file names
* We need 1 argument that is a null for execv.
* The caller fills in the editor's name.
* We fill in the initial search string.
* We fill in the arguments, and the null.
(*r_edargv
) = (char **)Calloc(n_pissed_on
+ 3, sizeof(char *));
(*r_edargc
) = n_pissed_on
+ 2;
(*r_edargv
)[1] = "+/###/";
fprintf(stdout
, "You touched file(s):");
for (fileindex
= 1; fileindex
<= nfiles
; fileindex
++){
if (!touchedfiles
[fileindex
])
errorp
= *(files
[fileindex
]);
fprintf(stdout
,"%s\"%s\"", sep
, errorp
->error_text
[0]);
(*r_edargv
)[n_pissed_on
++] = errorp
->error_text
[0];
(*r_edargv
)[n_pissed_on
] = 0;
fprintf(stdout
, "You didn't touch any files.\n");
--pat
; /* point to the period */
for (src
= &filename
[strlen(filename
)], --src
;
(src
> filename
) && (*src
!= '.'); --src
)
for (src
++, pat
++, osrc
= src
; *src
&& *pat
; src
= osrc
, pat
++){
for (; *src
/* not at end of the source */
&& *pat
/* not off end of pattern */
&& *pat
!= '.' /* not off end of sub pattern */
&& *pat
!= '*' /* not wild card */
&& *src
== *pat
; /* and equal... */
if (*src
== 0 && (*pat
== 0 || *pat
== '.' || *pat
== '*'))
if (*src
!= 0 && *pat
== '*')
while (*pat
&& *pat
!= '.')
FILE *o_touchedfile
; /* the old file */
FILE *n_touchedfile
; /* the new file */
char *canon_name
= "ErrorXXXXXX";
boolean tempfileopen
= FALSE
;
* open the file; guaranteed to be both readable and writable
* Well, if it isn't, then return TRUE if something failed
if ( (o_touchedfile
= fopen(name
, "r")) == NULL
){
fprintf(stderr
, "%s: Can't open file \"%s\" to touch (read).\n",
strcpy(n_name
, canon_name
);
if ( (n_touchedfile
= fopen(n_name
, "w")) == NULL
){
fprintf(stderr
,"%s: Can't open file \"%s\" to touch (write).\n",
* Position to the line (before, after) the line given by place
--place
; /* always insert messages before the offending line*/
for(; o_lineno
< place
; o_lineno
++, n_lineno
++){
if(fgets(edbuffer
, BUFSIZ
, o_touchedfile
) == NULL
)
fputs(edbuffer
, n_touchedfile
);
register struct error_desc
*errorp
;
int offset
= use_all
? 0 : 2;
fputs(lang_table
[errorp
->error_language
].lang_incomment
, n_touchedfile
);
fprintf(n_touchedfile
, "%d [%s] ",
lang_table
[errorp
->error_language
].lang_name
);
wordvprint(n_touchedfile
,
errorp
->error_lgtext
-offset
, errorp
->error_text
+offset
);
fputs(lang_table
[errorp
->error_language
].lang_outcomment
,n_touchedfile
);
for(; (bytes_read
= fread(edbuffer
, 1, sizeof(edbuffer
), o_touchedfile
))!= NULL
; ){
fwrite(edbuffer
, 1, bytes_read
, n_touchedfile
);
if (inquire("\nInterrupt: Do you want to continue?")){
errorprint(place
, errorp
, print_all
)
struct error_desc
*errorp
;
int offset
= print_all
? 0 : 2;
if (errorp
->error_e_class
== C_IGNORE
)
fprintf(place
, "[%s] ", lang_table
[errorp
->error_language
].lang_name
);
wordvprint(place
,errorp
->error_lgtext
-offset
,errorp
->error_text
+offset
);
boolean
inquire(fmt
, a1
, a2
)
fprintf(stderr
, fmt
, a1
, a2
);
} while (fgets(buffer
, 127, queryfile
) == NULL
);
if (ch
== 'Y' || ch
== 'y')
if (ch
== 'N' || ch
== 'n')
fprintf(stderr
, "Yes or No only!\n");
boolean
probethisfile(currentfilename
)
if (stat(currentfilename
, &statbuf
) != 0)
if ( (statbuf
.st_mode
&S_IREAD
) && (statbuf
.st_mode
&S_IWRITE
))