📄 touch.c
字号:
diverterrors(name, dest, files, ix, previewed, nterrors) char *name; int dest; Eptr **files; int ix; boolean previewed; int nterrors;{ int nerrors; reg Eptr *erpp; reg Eptr errorp; nerrors = files[ix+1] - files[ix]; if ( (nerrors != nterrors) && (!previewed) ){ fprintf(stdout, terse ? "Uninserted errors\n" : ">>Uninserted errors for file \"%s\" follow.\n", name); } EITERATE(erpp, files, ix){ errorp = *erpp; if (errorp->error_e_class != C_TRUE){ if (previewed || touchstatus == Q_NO) continue; errorprint(stdout, errorp, TRUE); continue; } switch (dest){ case TOSTDOUT: if (previewed || touchstatus == Q_NO) continue; errorprint(stdout,errorp, TRUE); break; case TOTHEFILE: insert(errorp->error_line); text(errorp, FALSE); break; } }}int oktotouch(filename) char *filename;{ extern char *suffixlist; reg char *src; reg char *pat; char *osrc; pat = suffixlist; if (pat == 0) return(0); if (*pat == '*') return(1); while (*pat++ != '.') continue; --pat; /* point to the period */ for (src = &filename[strlen(filename)], --src; (src > filename) && (*src != '.'); --src) continue; if (*src != '.') return(0); 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... */ src++, pat++) continue; if (*src == 0 && (*pat == 0 || *pat == '.' || *pat == '*')) return(1); if (*src != 0 && *pat == '*') return(1); while (*pat && *pat != '.') pat++; if (! *pat) return(0); } return(0);}/* * 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. */execvarg(n_pissed_on, r_argc, r_argv) int n_pissed_on; int *r_argc; char ***r_argv;{ Eptr p; char *sep; int fi; (*r_argv) = (char **)Calloc(n_pissed_on + 3, sizeof(char *)); (*r_argc) = n_pissed_on + 2; (*r_argv)[1] = "+1;/###/"; n_pissed_on = 2; if (!terse){ fprintf(stdout, "You touched file(s):"); sep = " "; } FILEITERATE(fi, 1){ if (!touchedfiles[fi]) continue; p = *(files[fi]); if (!terse){ fprintf(stdout,"%s\"%s\"", sep, p->error_text[0]); sep = ", "; } (*r_argv)[n_pissed_on++] = p->error_text[0]; } if (!terse) fprintf(stdout, "\n"); (*r_argv)[n_pissed_on] = 0;}FILE *o_touchedfile; /* the old file */FILE *n_touchedfile; /* the new file */char *o_name;char n_name[64];char *canon_name = _PATH_TMP;int o_lineno;int n_lineno;boolean tempfileopen = FALSE;/* * open the file; guaranteed to be both readable and writable * Well, if it isn't, then return TRUE if something failed */boolean edit(name) char *name;{ o_name = name; if ( (o_touchedfile = fopen(name, "r")) == NULL){ fprintf(stderr, "%s: Can't open file \"%s\" to touch (read).\n", processname, name); return(TRUE); } (void)strcpy(n_name, canon_name); (void)mktemp(n_name); if ( (n_touchedfile = fopen(n_name, "w")) == NULL){ fprintf(stderr,"%s: Can't open file \"%s\" to touch (write).\n", processname, name); return(TRUE); } tempfileopen = TRUE; n_lineno = 0; o_lineno = 0; return(FALSE);}/* * Position to the line (before, after) the line given by place */char edbuf[BUFSIZ];insert(place) int place;{ --place; /* always insert messages before the offending line*/ for(; o_lineno < place; o_lineno++, n_lineno++){ if(fgets(edbuf, BUFSIZ, o_touchedfile) == NULL) return; fputs(edbuf, n_touchedfile); }}text(p, use_all) reg Eptr p; boolean use_all;{ int offset = use_all ? 0 : 2; fputs(lang_table[p->error_language].lang_incomment, n_touchedfile); fprintf(n_touchedfile, "%d [%s] ", p->error_line, lang_table[p->error_language].lang_name); wordvprint(n_touchedfile, p->error_lgtext-offset, p->error_text+offset); fputs(lang_table[p->error_language].lang_outcomment,n_touchedfile); n_lineno++;}/* * write the touched file to its temporary copy, * then bring the temporary in over the local file */writetouched(overwrite) int overwrite;{ reg int nread; reg FILE *localfile; reg FILE *tmpfile; int botch; int oktorm; botch = 0; oktorm = 1; while((nread = fread(edbuf, 1, sizeof(edbuf), o_touchedfile)) != NULL){ if (nread != fwrite(edbuf, 1, nread, n_touchedfile)){ /* * Catastrophe in temporary area: file system full? */ botch = 1; fprintf(stderr, "%s: write failure: No errors inserted in \"%s\"\n", processname, o_name); } } fclose(n_touchedfile); fclose(o_touchedfile); /* * Now, copy the temp file back over the original * file, thus preserving links, etc */ if (botch == 0 && overwrite){ botch = 0; localfile = NULL; tmpfile = NULL; if ((localfile = fopen(o_name, "w")) == NULL){ fprintf(stderr, "%s: Can't open file \"%s\" to overwrite.\n", processname, o_name); botch++; } if ((tmpfile = fopen(n_name, "r")) == NULL){ fprintf(stderr, "%s: Can't open file \"%s\" to read.\n", processname, n_name); botch++; } if (!botch) oktorm = mustoverwrite(localfile, tmpfile); if (localfile != NULL) fclose(localfile); if (tmpfile != NULL) fclose(tmpfile); } if (oktorm == 0){ fprintf(stderr, "%s: Catastrophe: A copy of \"%s\": was saved in \"%s\"\n", processname, o_name, n_name); exit(1); } /* * Kiss the temp file good bye */ unlink(n_name); tempfileopen = FALSE; return(TRUE);}/* * return 1 if the tmpfile can be removed after writing it out */int mustoverwrite(preciousfile, tmpfile) FILE *preciousfile; FILE *tmpfile;{ int nread; while((nread = fread(edbuf, 1, sizeof(edbuf), tmpfile)) != NULL){ if (mustwrite(edbuf, nread, preciousfile) == 0) return(0); } return(1);}/* * return 0 on catastrophe */mustwrite(base, n, preciousfile) char *base; int n; FILE *preciousfile;{ int nwrote; if (n <= 0) return(1); nwrote = fwrite(base, 1, n, preciousfile); if (nwrote == n) return(1); perror(processname); switch(inquire(terse ? "Botch overwriting: retry? " : "Botch overwriting the source file: retry? ")){ case Q_YES: case Q_yes: mustwrite(base + nwrote, n - nwrote, preciousfile); return(1); case Q_NO: case Q_no: switch(inquire("Are you sure? ")){ case Q_YES: case Q_yes: return(0); case Q_NO: case Q_no: mustwrite(base + nwrote, n - nwrote, preciousfile); return(1); } default: return(0); }}voidonintr(){ switch(inquire(terse ? "\nContinue? " : "\nInterrupt: Do you want to continue? ")){ case Q_YES: case Q_yes: signal(SIGINT, onintr); return; default: if (tempfileopen){ /* * Don't overwrite the original file! */ writetouched(0); } exit(1); } /*NOTREACHED*/}errorprint(place, errorp, print_all) FILE *place; Eptr errorp; boolean print_all;{ int offset = print_all ? 0 : 2; if (errorp->error_e_class == C_IGNORE) return; fprintf(place, "[%s] ", lang_table[errorp->error_language].lang_name); wordvprint(place,errorp->error_lgtext-offset,errorp->error_text+offset); putc('\n', place);}int inquire(fmt, a1, a2) char *fmt; /*VARARGS1*/{ char buffer[128]; if (queryfile == NULL) return(0); for(;;){ do{ fflush(stdout); fprintf(stderr, fmt, a1, a2); fflush(stderr); } while (fgets(buffer, 127, queryfile) == NULL); switch(buffer[0]){ case 'Y': return(Q_YES); case 'y': return(Q_yes); case 'N': return(Q_NO); case 'n': return(Q_no); default: fprintf(stderr, "Yes or No only!\n"); } }}int probethisfile(name) char *name;{ struct stat statbuf; if (stat(name, &statbuf) < 0) return(F_NOTEXIST); if((statbuf.st_mode & S_IREAD) == 0) return(F_NOTREAD); if((statbuf.st_mode & S_IWRITE) == 0) return(F_NOTWRITE); return(F_TOUCHIT);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -