📄 touch.c
字号:
/* * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)touch.c 8.1 (Berkeley) 6/6/93";#endif /* not lint */#include <sys/types.h>#include <sys/stat.h>#include <signal.h>#include <unistd.h>#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include "error.h"#include "pathnames.h"/* * Iterate through errors */#define EITERATE(p, fv, i) for (p = fv[i]; p < fv[i+1]; p++)#define ECITERATE(ei, p, lb) for (ei = lb; p = errors[ei],ei < nerrors; ei++)#define FILEITERATE(fi, lb) for (fi = lb; fi <= nfiles; fi++)int touchstatus = Q_YES;findfiles(nerrors, errors, r_nfiles, r_files) int nerrors; Eptr *errors; int *r_nfiles; Eptr ***r_files;{ int nfiles; Eptr **files; char *name; reg int ei; int fi; reg Eptr errorp; nfiles = countfiles(errors); files = (Eptr**)Calloc(nfiles + 3, sizeof (Eptr*)); touchedfiles = (boolean *)Calloc(nfiles+3, sizeof(boolean)); /* * Now, partition off the error messages * into those that are synchronization, discarded or * not specific to any file, and those that were * nulled or true errors. */ files[0] = &errors[0]; ECITERATE(ei, errorp, 0){ if ( ! (NOTSORTABLE(errorp->error_e_class))) break; } /* * Now, and partition off all error messages * for a given file. */ files[1] = &errors[ei]; touchedfiles[0] = touchedfiles[1] = FALSE; name = "\1"; fi = 1; ECITERATE(ei, errorp, ei){ 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]; touchedfiles[fi] = FALSE; files[fi] = &errors[ei]; fi++; } } } files[fi] = &errors[nerrors]; *r_nfiles = nfiles; *r_files = files;}int countfiles(errors) Eptr *errors;{ char *name; int ei; reg Eptr errorp; int nfiles; nfiles = 0; name = "\1"; ECITERATE(ei, errorp, 0){ if (SORTABLE(errorp->error_e_class)){ if (strcmp(errorp->error_text[0],name) != 0){ nfiles++; name = errorp->error_text[0]; } } } return(nfiles);}char *class_table[] = { /*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_TRUE 7 */ "true", /*C_DUPL 8 */ "duplicated"};int class_count[C_LAST - C_FIRST] = {0};filenames(nfiles, files) int nfiles; Eptr **files;{ reg int fi; char *sep = " "; extern char *class_table[]; int someerrors; /* * first, simply dump out errors that * don't pertain to any file */ someerrors = nopertain(files); if (nfiles){ someerrors++; fprintf(stdout, terse ? "%d file%s" : "%d file%s contain%s errors", nfiles, plural(nfiles), verbform(nfiles)); if (!terse){ FILEITERATE(fi, 1){ fprintf(stdout, "%s\"%s\" (%d)", sep, (*files[fi])->error_text[0], files[fi+1] - files[fi]); sep = ", "; } } fprintf(stdout, "\n"); } if (!someerrors) fprintf(stdout, "No errors.\n");}/* * Dump out errors that don't pertain to any file */int nopertain(files) Eptr **files;{ int type; int someerrors = 0; reg Eptr *erpp; reg Eptr errorp; if (files[1] - files[0] <= 0) return(0); for(type = C_UNKNOWN; NOTSORTABLE(type); type++){ if (class_count[type] <= 0) continue; if (type > C_SYNC) someerrors++; if (terse){ fprintf(stdout, "\t%d %s errors NOT PRINTED\n", class_count[type], class_table[type]); } else { fprintf(stdout, "\n\t%d %s errors follow\n", class_count[type], class_table[type]); EITERATE(erpp, files, 0){ errorp = *erpp; if (errorp->error_e_class == type){ errorprint(stdout, errorp, TRUE); } } } } return(someerrors);}extern boolean notouch;boolean touchfiles(nfiles, files, r_edargc, r_edargv) int nfiles; Eptr **files; int *r_edargc; char ***r_edargv;{ char *name; reg Eptr errorp; reg int fi; reg Eptr *erpp; int ntrueerrors; boolean scribbled; int n_pissed_on; /* # of file touched*/ int spread; FILEITERATE(fi, 1){ name = (*files[fi])->error_text[0]; spread = files[fi+1] - files[fi]; fprintf(stdout, terse ? "\"%s\" has %d error%s, " : "\nFile \"%s\" has %d error%s.\n" , name ,spread ,plural(spread)); /* * First, iterate through all error messages in this file * to see how many of the error messages really will * get inserted into the file. */ ntrueerrors = 0; EITERATE(erpp, files, fi){ errorp = *erpp; if (errorp->error_e_class == C_TRUE) ntrueerrors++; } fprintf(stdout, terse ? "insert %d\n" : "\t%d of these errors can be inserted into the file.\n", ntrueerrors); hackfile(name, files, fi, ntrueerrors); } scribbled = FALSE; n_pissed_on = 0; FILEITERATE(fi, 1){ scribbled |= touchedfiles[fi]; n_pissed_on++; } if (scribbled){ /* * Construct an execv argument */ execvarg(n_pissed_on, r_edargc, r_edargv); return(TRUE); } else { if (!terse) fprintf(stdout, "You didn't touch any files.\n"); return(FALSE); }}hackfile(name, files, ix, nerrors) char *name; Eptr **files; int ix;{ boolean previewed; int errordest; /* where errors go*/ if (!oktotouch(name)) { previewed = FALSE; errordest = TOSTDOUT; } else { previewed = preview(name, nerrors, files, ix); errordest = settotouch(name); } if (errordest != TOSTDOUT) touchedfiles[ix] = TRUE; if (previewed && (errordest == TOSTDOUT)) return; diverterrors(name, errordest, files, ix, previewed, nerrors); if (errordest == TOTHEFILE){ /* * overwrite the original file */ writetouched(1); }}boolean preview(name, nerrors, files, ix) char *name; int nerrors; Eptr **files; int ix;{ int back; reg Eptr *erpp; if (nerrors <= 0) return(FALSE); back = FALSE; if(query){ switch(inquire(terse ? "Preview? " : "Do you want to preview the errors first? ")){ case Q_YES: case Q_yes: back = TRUE; EITERATE(erpp, files, ix){ errorprint(stdout, *erpp, TRUE); } if (!terse) fprintf(stdout, "\n"); default: break; } } return(back);}int settotouch(name) char *name;{ int dest = TOSTDOUT; if (query){ switch(touchstatus = inquire(terse ? "Touch? " : "Do you want to touch file \"%s\"? ", name)){ case Q_NO: case Q_no: return(dest); default: break; } } switch(probethisfile(name)){ case F_NOTREAD: dest = TOSTDOUT; fprintf(stdout, terse ? "\"%s\" unreadable\n" : "File \"%s\" is unreadable\n", name); break; case F_NOTWRITE: dest = TOSTDOUT; fprintf(stdout, terse ? "\"%s\" unwritable\n" : "File \"%s\" is unwritable\n", name); break; case F_NOTEXIST: dest = TOSTDOUT; fprintf(stdout, terse ? "\"%s\" not found\n" : "Can't find file \"%s\" to insert error messages into.\n", name); break; default: dest = edit(name) ? TOSTDOUT : TOTHEFILE; break; } return(dest);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -