summaryrefslogtreecommitdiff
path: root/patch.c
diff options
context:
space:
mode:
Diffstat (limited to 'patch.c')
-rw-r--r--patch.c330
1 files changed, 220 insertions, 110 deletions
diff --git a/patch.c b/patch.c
index 7e196ce..e976204 100644
--- a/patch.c
+++ b/patch.c
@@ -1,6 +1,6 @@
/* patch - a program to apply diffs to original files */
-/* $Id: patch.c,v 1.17 1997/05/26 05:34:43 eggert Exp $ */
+/* $Id: patch.c,v 1.22 1997/06/17 22:32:49 eggert Exp $ */
/*
Copyright 1984, 1985, 1986, 1987, 1988 Larry Wall
@@ -34,25 +34,46 @@ If not, write to the Free Software Foundation,
#include <util.h>
#include <version.h>
+#if HAVE_UTIME_H
+# include <utime.h>
+#endif
+/* Some nonstandard hosts don't declare this structure even in <utime.h>. */
+#if ! HAVE_STRUCT_UTIMBUF
+struct utimbuf
+{
+ time_t actime;
+ time_t modtime;
+};
+#endif
+
+/* Output stream state. */
+struct outstate
+{
+ FILE *ofp;
+ int after_newline;
+ int zero_output;
+};
+
/* procedures */
static FILE *create_output_file PARAMS ((char const *));
static LINENUM locate_hunk PARAMS ((LINENUM));
-static bool apply_hunk PARAMS ((bool *, LINENUM));
-static bool copy_till PARAMS ((bool *, LINENUM));
+static bool apply_hunk PARAMS ((struct outstate *, LINENUM));
+static bool copy_till PARAMS ((struct outstate *, LINENUM));
static bool patch_match PARAMS ((LINENUM, LINENUM, LINENUM, LINENUM));
static bool similar PARAMS ((char const *, size_t, char const *, size_t));
-static bool spew_output PARAMS ((bool *));
+static bool spew_output PARAMS ((struct outstate *));
static char const *make_temp PARAMS ((int));
-static int numeric_optarg PARAMS ((char const *));
+static int numeric_string PARAMS ((char const *, int, char const *));
static void abort_hunk PARAMS ((void));
static void cleanup PARAMS ((void));
static void get_some_switches PARAMS ((void));
-static void init_output PARAMS ((char const *));
+static void init_output PARAMS ((char const *, struct outstate *));
static void init_reject PARAMS ((char const *));
static void reinitialize_almost_everything PARAMS ((void));
static void usage PARAMS ((FILE *, int)) __attribute__((noreturn));
+static int backup_if_mismatch;
static int remove_empty_files;
/* TRUE if -R was specified on command line. */
@@ -70,10 +91,8 @@ static char const end_defined[] = "\n#endif /* %s */\n";
static int Argc;
static char * const *Argv;
-static FILE *ofp; /* output file pointer */
static FILE *rejfp; /* reject file pointer */
-static char *output;
static char const *patchname;
static char *rejname;
static char const * volatile TMPREJNAME;
@@ -94,7 +113,9 @@ main(argc,argv)
int argc;
char **argv;
{
+ char const *val;
bool somefailed = FALSE;
+ struct outstate outstate;
init_time ();
@@ -105,8 +126,11 @@ char **argv;
strippath = INT_MAX;
- patch_get = getenv ("PATCH_GET") != 0;
posixly_correct = getenv ("POSIXLY_CORRECT") != 0;
+ backup_if_mismatch = ! posixly_correct;
+ patch_get = ((val = getenv ("PATCH_GET"))
+ ? numeric_string (val, 1, "PATCH_GET value")
+ : posixly_correct - 1);
{
char const *v;
@@ -134,8 +158,7 @@ char **argv;
Argv = argv;
get_some_switches();
- if (output)
- init_output (output);
+ init_output (outfile, &outstate);
/* Make sure we clean up in case of disaster. */
set_signals(0);
@@ -147,22 +170,32 @@ char **argv;
) { /* for each patch in patch file */
int hunk = 0;
int failed = 0;
- char *outname = output ? output : inname;
+ int mismatch = 0;
+ char *outname = outfile ? outfile : inname;
if (!skip_rest_of_patch)
get_input_file (inname, outname);
if (diff_type == ED_DIFF) {
+ outstate.zero_output = 0;
if (! dry_run)
- do_ed_script (ofp);
+ {
+ do_ed_script (outstate.ofp);
+ if (! outfile)
+ {
+ struct stat statbuf;
+ if (stat (TMPOUTNAME, &statbuf) != 0)
+ pfatal ("%s", TMPOUTNAME);
+ outstate.zero_output = statbuf.st_size == 0;
+ }
+ }
} else {
int got_hunk;
int apply_anyway = 0;
- bool after_newline = TRUE;
/* initialize the patched file */
- if (!skip_rest_of_patch && !output)
- init_output(TMPOUTNAME);
+ if (! skip_rest_of_patch && ! outfile)
+ init_output (TMPOUTNAME, &outstate);
/* initialize reject file */
init_reject(TMPREJNAME);
@@ -188,7 +221,10 @@ char **argv;
if (!skip_rest_of_patch) {
do {
where = locate_hunk(fuzz);
- if (hunk == 1 && !where && !(force|apply_anyway)) {
+ if (! where || fuzz || last_offset)
+ mismatch = 1;
+ if (hunk == 1 && ! where && ! (force | apply_anyway)
+ && reverse == reverse_flag_specified) {
/* dwim for reversed patch? */
if (!pch_swap()) {
say (
@@ -221,10 +257,10 @@ char **argv;
&& ++fuzz <= mymaxfuzz);
if (skip_rest_of_patch) { /* just got decided */
- if (ofp && !output)
+ if (outstate.ofp && ! outfile)
{
- fclose (ofp);
- ofp = 0;
+ fclose (outstate.ofp);
+ outstate.ofp = 0;
}
}
}
@@ -233,26 +269,27 @@ char **argv;
if (skip_rest_of_patch) {
abort_hunk();
failed++;
- if (verbosity != SILENT)
+ if (verbosity == VERBOSE)
say ("Hunk #%d ignored at %ld.\n", hunk, newwhere);
}
else if (!where
|| (where == 1 && pch_says_nonexistent (reverse)
- && input_lines)) {
+ && instat.st_size)) {
if (where)
- say ("\nPatch attempted to create file `%s', which already exists.\n", inname);
+ say ("Patch attempted to create file `%s', which already exists.\n", inname);
abort_hunk();
failed++;
if (verbosity != SILENT)
say ("Hunk #%d FAILED at %ld.\n", hunk, newwhere);
}
- else {
- if (! apply_hunk (&after_newline, where)) {
- abort_hunk ();
- failed++;
- if (verbosity != SILENT)
- say ("Hunk #%d FAILED at %ld.\n", hunk, newwhere);
- } else if (verbosity == VERBOSE) {
+ else if (! apply_hunk (&outstate, where)) {
+ abort_hunk ();
+ failed++;
+ if (verbosity != SILENT)
+ say ("Hunk #%d FAILED at %ld.\n", hunk, newwhere);
+ } else {
+ if (verbosity == VERBOSE
+ || (verbosity != SILENT && (fuzz || last_offset))) {
say ("Hunk #%d succeeded at %ld", hunk, newwhere);
if (fuzz)
say (" with fuzz %ld", fuzz);
@@ -265,13 +302,13 @@ char **argv;
}
if (got_hunk < 0 && using_plan_a) {
- if (output)
+ if (outfile)
fatal ("out of memory using Plan A");
say ("\n\nRan out of memory using Plan A -- trying again...\n\n");
- if (ofp)
+ if (outstate.ofp)
{
- fclose (ofp);
- ofp = 0;
+ fclose (outstate.ofp);
+ outstate.ofp = 0;
}
fclose (rejfp);
continue;
@@ -281,19 +318,21 @@ char **argv;
if (!skip_rest_of_patch)
{
assert (hunk);
- skip_rest_of_patch = ! spew_output (&after_newline);
+ if (! spew_output (&outstate))
+ {
+ say ("Skipping patch.\n");
+ skip_rest_of_patch = TRUE;
+ }
}
}
/* and put the output where desired */
ignore_signals ();
- if (!skip_rest_of_patch && !output) {
- struct stat statbuf;
-
- if ((remove_empty_files
- || (pch_says_nonexistent (reverse ^ 1) && !posixly_correct))
- && stat (TMPOUTNAME, &statbuf) == 0
- && statbuf.st_size == 0)
+ if (! skip_rest_of_patch && ! outfile) {
+ if (outstate.zero_output
+ && (remove_empty_files
+ || (pch_says_nonexistent (reverse ^ 1) == 2
+ && ! posixly_correct)))
{
if (verbosity == VERBOSE)
say ("Removing file `%s'%s.\n", outname,
@@ -301,16 +340,49 @@ char **argv;
if (! dry_run)
{
move_file ((char *) 0, outname, (mode_t) 0,
- backup_type != none);
+ (backup_type != none
+ || (backup_if_mismatch && (mismatch | failed))));
removedirs (outname);
}
}
else
{
+ if (! outstate.zero_output
+ && pch_says_nonexistent (reverse ^ 1))
+ {
+ mismatch = 1;
+ if (verbosity != SILENT)
+ say ("File `%s' is not empty after patch, as expected.\n",
+ outname);
+ }
+
if (! dry_run)
{
+ time_t t;
+
move_file (TMPOUTNAME, outname, instat.st_mode,
- backup_type != none);
+ (backup_type != none
+ || (backup_if_mismatch && (mismatch | failed))));
+
+ if ((set_time | set_utc)
+ && (t = pch_timestamp (reverse ^ 1)) != (time_t) -1)
+ {
+ struct utimbuf utimbuf;
+ utimbuf.actime = utimbuf.modtime = t;
+
+ if (! force && ! inerrno
+ && ! pch_says_nonexistent (reverse)
+ && (t = pch_timestamp (reverse)) != (time_t) -1
+ && t != instat.st_mtime)
+ say ("not setting time of file `%s' (time mismatch)\n",
+ outname);
+ else if (! force && (mismatch | failed))
+ say ("not setting time of file `%s' (contents mismatch)\n",
+ outname);
+ else if (utime (outname, &utimbuf) != 0)
+ pfatal ("can't set timestamp on file `%s'", outname);
+ }
+
if (! inerrno && chmod (outname, instat.st_mode) != 0)
pfatal ("can't set permissions on file `%s'", outname);
}
@@ -348,7 +420,7 @@ char **argv;
}
set_signals (1);
}
- if (ofp && (ferror (ofp) || fclose (ofp) != 0))
+ if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0))
write_fatal ();
cleanup ();
if (somefailed)
@@ -385,7 +457,7 @@ reinitialize_almost_everything()
skip_rest_of_patch = FALSE;
}
-static char const shortopts[] = "bB:cd:D:eEfF:gGi:lnNo:p:r:RstuvV:x:Y:z:";
+static char const shortopts[] = "bB:cd:D:eEfF:g:i:lnNo:p:r:RstTuvV:x:Y:z:Z";
static struct option const longopts[] =
{
{"backup", no_argument, NULL, 'b'},
@@ -398,7 +470,6 @@ static struct option const longopts[] =
{"force", no_argument, NULL, 'f'},
{"fuzz", required_argument, NULL, 'F'},
{"get", no_argument, NULL, 'g'},
- {"no-get", no_argument, NULL, 'G'},
{"input", required_argument, NULL, 'i'},
{"ignore-whitespace", no_argument, NULL, 'l'},
{"normal", no_argument, NULL, 'n'},
@@ -410,16 +481,20 @@ static struct option const longopts[] =
{"quiet", no_argument, NULL, 's'},
{"silent", no_argument, NULL, 's'},
{"batch", no_argument, NULL, 't'},
+ {"set-time", no_argument, NULL, 'T'},
{"unified", no_argument, NULL, 'u'},
{"version", no_argument, NULL, 'v'},
{"version-control", required_argument, NULL, 'V'},
{"debug", required_argument, NULL, 'x'},
{"basename-prefix", required_argument, NULL, 'Y'},
{"suffix", required_argument, NULL, 'z'},
+ {"set-utc", no_argument, NULL, 'Z'},
{"dry-run", no_argument, NULL, 129},
{"verbose", no_argument, NULL, 130},
{"binary", no_argument, NULL, 131},
{"help", no_argument, NULL, 132},
+ {"backup-if-mismatch", no_argument, NULL, 133},
+ {"no-backup-if-mismatch", no_argument, NULL, 134},
{NULL, no_argument, NULL, 0}
};
@@ -449,18 +524,22 @@ static char const *const option_help[] =
" -D NAME --ifdef=NAME Make merged if-then-else output using NAME.",
" -E --remove-empty-files Remove output files that are empty after patching.",
"",
+" -Z --set-utc Set times of patched files, assuming diff uses UTC (GMT).",
+" -T --set-time Likewise, assuming local time.",
+"",
"Backup and version control options:",
"",
" -V STYLE --version-control=STYLE Use STYLE version control.",
" STYLE is either 'simple', 'numbered', or 'existing'.",
"",
-" -b --backup Save the original contents of each file F into F.orig.",
+" -b --backup Back up the original contents of each file.",
+" --backup-if-mismatch Back up if the patch does not match exactly.",
+" --no-backup-if-mismatch Back up mismatches only if otherwise requested.",
" -B PREFIX --prefix=PREFIX Prepend PREFIX to backup file names.",
" -Y PREFIX --basename-prefix=PREFIX Prepend PREFIX to backup file basenames.",
" -z SUFFIX --suffix=SUFFIX Append SUFFIX to backup file names.",
"",
-" -g --get Get files from RCS or SCCS.",
-" -G --no-get Do not get files.",
+" -g NUM --get=NUM Get files from RCS or SCCS if positive; ask if negative.",
"",
"Miscellaneous options:",
"",
@@ -544,7 +623,6 @@ get_some_switches()
if (!*optarg)
fatal ("backup prefix is empty");
origprae = savestr (optarg);
- backup_type = simple;
break;
case 'c':
diff_type = CONTEXT_DIFF;
@@ -566,13 +644,10 @@ get_some_switches()
force = TRUE;
break;
case 'F':
- maxfuzz = numeric_optarg ("fuzz factor");
+ maxfuzz = numeric_string (optarg, 0, "fuzz factor");
break;
case 'g':
- patch_get = 1;
- break;
- case 'G':
- patch_get = 0;
+ patch_get = numeric_string (optarg, 1, "get option value");
break;
case 'i':
patchname = savestr (optarg);
@@ -589,10 +664,10 @@ get_some_switches()
case 'o':
if (strcmp (optarg, "-") == 0)
fatal ("can't output patches to standard output");
- output = savestr (optarg);
+ outfile = savestr (optarg);
break;
case 'p':
- strippath = numeric_optarg ("strip count");
+ strippath = numeric_string (optarg, 0, "strip count");
break;
case 'r':
rejname = savestr (optarg);
@@ -607,6 +682,9 @@ get_some_switches()
case 't':
batch = TRUE;
break;
+ case 'T':
+ set_time = 1;
+ break;
case 'u':
diff_type = UNI_DIFF;
break;
@@ -619,21 +697,22 @@ get_some_switches()
break;
#if DEBUGGING
case 'x':
- debug = numeric_optarg ("debugging option");
+ debug = numeric_string (optarg, 1, "debugging option");
break;
#endif
case 'Y':
if (!*optarg)
fatal ("backup basename prefix is empty");
origbase = savestr (optarg);
- backup_type = simple;
break;
case 'z':
case_z:
if (!*optarg)
fatal ("backup suffix is empty");
simple_backup_suffix = savestr (optarg);
- backup_type = simple;
+ break;
+ case 'Z':
+ set_utc = 1;
break;
case 129:
dry_run = TRUE;
@@ -648,6 +727,12 @@ get_some_switches()
break;
case 132:
usage (stdout, 0);
+ case 133:
+ backup_if_mismatch = 1;
+ break;
+ case 134:
+ backup_if_mismatch = 0;
+ break;
default:
usage (stderr, 2);
}
@@ -657,6 +742,7 @@ get_some_switches()
if (optind < Argc)
{
inname = savestr (Argv[optind++]);
+ invc = -1;
if (optind < Argc)
{
patchname = savestr (Argv[optind++]);
@@ -670,30 +756,41 @@ get_some_switches()
}
}
-/* Handle a numeric option of type ARGTYPE_MSGID by converting
- optarg to a nonnegative integer, returning the result. */
+/* Handle STRING (possibly negative if NEGATIVE_ALLOWED is nonzero)
+ of type ARGTYPE_MSGID by converting it to an integer,
+ returning the result. */
static int
-numeric_optarg (argtype_msgid)
+numeric_string (string, negative_allowed, argtype_msgid)
+ char const *string;
+ int negative_allowed;
char const *argtype_msgid;
{
int value = 0;
- char const *p = optarg;
+ char const *p = string;
+ int sign = *p == '-' ? -1 : 1;
+
+ p += *p == '-' || *p == '+';
do
{
int v10 = value * 10;
int digit = *p - '0';
+ int signed_digit = sign * digit;
+ int next_value = v10 + signed_digit;
if (9 < (unsigned) digit)
- fatal ("%s `%s' is not a number", argtype_msgid, optarg);
+ fatal ("%s `%s' is not a number", argtype_msgid, string);
- if (v10 / 10 != value || v10 + digit < v10)
- fatal ("%s `%s' is too large", argtype_msgid, optarg);
+ if (v10 / 10 != value || (next_value < v10) != (signed_digit < 0))
+ fatal ("%s `%s' is too large", argtype_msgid, string);
- value = v10 + digit;
+ value = next_value;
}
while (*++p);
+ if (value < 0 && ! negative_allowed)
+ fatal ("%s `%s' is negative", argtype_msgid, string);
+
return value;
}
@@ -825,9 +922,9 @@ abort_hunk()
/* We found where to apply it (we hope), so do it. */
static bool
-apply_hunk (after_newline, where)
-bool *after_newline;
-LINENUM where;
+apply_hunk (outstate, where)
+ struct outstate *outstate;
+ LINENUM where;
{
register LINENUM old = 1;
register LINENUM lastline = pch_ptrn_lines ();
@@ -835,7 +932,7 @@ LINENUM where;
register enum {OUTSIDE, IN_IFNDEF, IN_IFDEF, IN_ELSE} def_state = OUTSIDE;
register char const *R_do_defines = do_defines;
register LINENUM pat_end = pch_end ();
- register FILE *fp = ofp;
+ register FILE *fp = outstate->ofp;
where--;
while (pch_char(new) == '=' || pch_char(new) == '\n')
@@ -843,21 +940,23 @@ LINENUM where;
while (old <= lastline) {
if (pch_char(old) == '-') {
- assert (*after_newline);
- if (! copy_till (after_newline, where + old - 1))
+ assert (outstate->after_newline);
+ if (! copy_till (outstate, where + old - 1))
return FALSE;
if (R_do_defines) {
if (def_state == OUTSIDE) {
- fprintf (fp, *after_newline + if_defined, R_do_defines);
+ fprintf (fp, outstate->after_newline + if_defined,
+ R_do_defines);
def_state = IN_IFNDEF;
}
else if (def_state == IN_IFDEF) {
- fprintf (fp, *after_newline + else_defined);
+ fprintf (fp, outstate->after_newline + else_defined);
def_state = IN_ELSE;
}
if (ferror (fp))
write_fatal ();
- *after_newline = pch_write_line (old, fp);
+ outstate->after_newline = pch_write_line (old, fp);
+ outstate->zero_output = 0;
}
last_frozen_line++;
old++;
@@ -866,21 +965,23 @@ LINENUM where;
break;
}
else if (pch_char(new) == '+') {
- if (! copy_till (after_newline, where + old - 1))
+ if (! copy_till (outstate, where + old - 1))
return FALSE;
if (R_do_defines) {
if (def_state == IN_IFNDEF) {
- fprintf (fp, *after_newline + else_defined);
+ fprintf (fp, outstate->after_newline + else_defined);
def_state = IN_ELSE;
}
else if (def_state == OUTSIDE) {
- fprintf (fp, *after_newline + if_defined, R_do_defines);
+ fprintf (fp, outstate->after_newline + if_defined,
+ R_do_defines);
def_state = IN_IFDEF;
}
if (ferror (fp))
write_fatal ();
}
- *after_newline = pch_write_line (new, fp);
+ outstate->after_newline = pch_write_line (new, fp);
+ outstate->zero_output = 0;
new++;
}
else if (pch_char(new) != pch_char(old)) {
@@ -892,10 +993,10 @@ LINENUM where;
pch_hunk_beg() + new);
}
else if (pch_char(new) == '!') {
- assert (*after_newline);
- if (! copy_till (after_newline, where + old - 1))
+ assert (outstate->after_newline);
+ if (! copy_till (outstate, where + old - 1))
return FALSE;
- assert (*after_newline);
+ assert (outstate->after_newline);
if (R_do_defines) {
fprintf (fp, not_defined, R_do_defines);
if (ferror (fp))
@@ -906,7 +1007,7 @@ LINENUM where;
do
{
if (R_do_defines) {
- *after_newline = pch_write_line (old, fp);
+ outstate->after_newline = pch_write_line (old, fp);
}
last_frozen_line++;
old++;
@@ -914,7 +1015,7 @@ LINENUM where;
while (pch_char (old) == '!');
if (R_do_defines) {
- fprintf (fp, *after_newline + else_defined);
+ fprintf (fp, outstate->after_newline + else_defined);
if (ferror (fp))
write_fatal ();
def_state = IN_ELSE;
@@ -922,54 +1023,59 @@ LINENUM where;
do
{
- *after_newline = pch_write_line (new, fp);
+ outstate->after_newline = pch_write_line (new, fp);
new++;
}
while (pch_char (new) == '!');
+ outstate->zero_output = 0;
}
else {
assert(pch_char(new) == ' ');
old++;
new++;
if (R_do_defines && def_state != OUTSIDE) {
- fprintf (fp, *after_newline + end_defined, R_do_defines);
+ fprintf (fp, outstate->after_newline + end_defined,
+ R_do_defines);
if (ferror (fp))
write_fatal ();
- *after_newline = TRUE;
+ outstate->after_newline = 1;
def_state = OUTSIDE;
}
}
}
if (new <= pat_end && pch_char(new) == '+') {
- if (! copy_till (after_newline, where + old - 1))
+ if (! copy_till (outstate, where + old - 1))
return FALSE;
if (R_do_defines) {
if (def_state == OUTSIDE) {
- fprintf (fp, *after_newline + if_defined, R_do_defines);
+ fprintf (fp, outstate->after_newline + if_defined,
+ R_do_defines);
def_state = IN_IFDEF;
}
else if (def_state == IN_IFNDEF) {
- fprintf (fp, *after_newline + else_defined);
+ fprintf (fp, outstate->after_newline + else_defined);
def_state = IN_ELSE;
}
if (ferror (fp))
write_fatal ();
+ outstate->zero_output = 0;
}
do
{
- if (!*after_newline && putc ('\n', fp) == EOF)
+ if (! outstate->after_newline && putc ('\n', fp) == EOF)
write_fatal ();
- *after_newline = pch_write_line (new, fp);
+ outstate->after_newline = pch_write_line (new, fp);
+ outstate->zero_output = 0;
new++;
}
while (new <= pat_end && pch_char (new) == '+');
}
if (R_do_defines && def_state != OUTSIDE) {
- fprintf (fp, *after_newline + end_defined, R_do_defines);
+ fprintf (fp, outstate->after_newline + end_defined, R_do_defines);
if (ferror (fp))
write_fatal ();
- *after_newline = TRUE;
+ outstate->after_newline = 1;
}
return TRUE;
}
@@ -990,10 +1096,13 @@ create_output_file (name)
/* Open the new file. */
static void
-init_output(name)
+init_output (name, outstate)
char const *name;
+ struct outstate *outstate;
{
- ofp = create_output_file (name);
+ outstate->ofp = name ? create_output_file (name) : (FILE *) 0;
+ outstate->after_newline = 1;
+ outstate->zero_output = 1;
}
/* Open a file to put hunks we can't locate. */
@@ -1008,12 +1117,12 @@ init_reject(name)
/* Copy input file to output, up to wherever hunk is to be applied. */
static bool
-copy_till (after_newline, lastline)
- register bool *after_newline;
+copy_till (outstate, lastline)
+ register struct outstate *outstate;
register LINENUM lastline;
{
register LINENUM R_last_frozen_line = last_frozen_line;
- register FILE *fp = ofp;
+ register FILE *fp = outstate->ofp;
register char const *s;
size_t size;
@@ -1027,10 +1136,11 @@ copy_till (after_newline, lastline)
s = ifetch (++R_last_frozen_line, 0, &size);
if (size)
{
- if ((!*after_newline && putc ('\n', fp) == EOF)
+ if ((! outstate->after_newline && putc ('\n', fp) == EOF)
|| ! fwrite (s, sizeof *s, size, fp))
write_fatal ();
- *after_newline = s[size - 1] == '\n';
+ outstate->after_newline = s[size - 1] == '\n';
+ outstate->zero_output = 0;
}
}
last_frozen_line = R_last_frozen_line;
@@ -1040,21 +1150,21 @@ copy_till (after_newline, lastline)
/* Finish copying the input file to the output file. */
static bool
-spew_output (after_newline)
- bool *after_newline;
+spew_output (outstate)
+ struct outstate *outstate;
{
if (debug & 256)
say ("il=%ld lfl=%ld\n", input_lines, last_frozen_line);
if (last_frozen_line < input_lines)
- if (! copy_till (after_newline, input_lines))
+ if (! copy_till (outstate, input_lines))
return FALSE;
- if (ofp && !output)
+ if (outstate->ofp && ! outfile)
{
- if (fclose (ofp) != 0)
+ if (fclose (outstate->ofp) != 0)
write_fatal ();
- ofp = 0;
+ outstate->ofp = 0;
}
return TRUE;