mirror of
https://https.git.savannah.gnu.org/git/patch.git
synced 2026-01-27 01:44:34 +00:00
Import of patch-2.4.tar.gz
This commit is contained in:
parent
1adb4535a3
commit
6263c220df
263
ChangeLog
263
ChangeLog
@ -1,3 +1,222 @@
|
||||
1997-06-19 Paul Eggert <eggert@pogo.gnu.ai.mit.edu>
|
||||
|
||||
* configure.in (VERSION): Version 2.4 released.
|
||||
* NEWS: Patch is now verbose when patches do not match exactly.
|
||||
|
||||
1997-06-17 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* pc/djgpp/configure.sed (config.h): Remove redundant $(srcdir).
|
||||
|
||||
* configure.in (VERSION): Bump to 2.3.9.
|
||||
* patch.c (main): By default, warn about hunks that succeed
|
||||
with nonzero offset.
|
||||
* patch.man: Add LC_ALL=C advice for making patches.
|
||||
* pc/djgpp/configure.sed (config.h): Fix paths to dependent files.
|
||||
|
||||
1997-06-17 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION): Bump to 2.3.8.
|
||||
|
||||
* pch.c (open_patch_file): Test stdin for fseekability.
|
||||
(intuit_diff_type): Missing context diff headers are now warnings,
|
||||
not errors; some people use patches with them (e.g. when retrying
|
||||
rejects).
|
||||
|
||||
* patch.c (struct outstate):
|
||||
New type, collecting together some output state vars.
|
||||
(apply_hunk, copy_till, spew_output, init_output): Use it.
|
||||
Keep track of whether some output has been generated.
|
||||
(backup_if_mismatch): New var.
|
||||
(ofp): Remove, in favor of local struct outstate vars.
|
||||
(main): Use struct outstate. Initialize backup_if_mismatch to
|
||||
be the inverse of posixly_correct. Keep track of whether mismatches
|
||||
occur, and use this to implement backup_if_mismatch.
|
||||
Report files that are not empty after patching, but should be.
|
||||
(longopts, option_help, get_some_switches): New options
|
||||
--backup-if-mismatch, --no-backup-if-mismatch.
|
||||
(get_some_switches): -B, -Y, -z no longer set backup_type.
|
||||
* backupfile.c (find_backup_file_name):
|
||||
Treat backup_type == none like simple.
|
||||
|
||||
* Makefile.in (CONFIG_HDRS):
|
||||
Remove var; no longer needed by djgpp port.
|
||||
(DISTFILES_PC_DJGPP): Rename pc/djgpp/config.sed to
|
||||
pc/djgpp/configure.sed; remove pc/djgpp/config.h in favor of
|
||||
new file that edits it, called pc/djgpp/config.sed.
|
||||
* pc/djgpp/configure.bat: Rename config.sed to configure.sed.
|
||||
* pc/djgpp/configure.sed (CONFIG_HDRS): Remove.
|
||||
(config.h): Add rule to build this from config.hin and
|
||||
pc/djgpp/config.sed.
|
||||
* pc/djgpp/config.sed:
|
||||
Convert from .h file to .sed script that generates .h file.
|
||||
|
||||
* NEWS: Describe --backup-if-mismatch, --no-backup-if-mismatch.
|
||||
* patch.man:
|
||||
Describe new options --backup-if-mismatch, --no-backup-if-mismatch
|
||||
and their ramifications. Use unreadable backup to represent
|
||||
nonexistent file.
|
||||
|
||||
1997-06-12 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION): Bump to 2.3.7.
|
||||
(AC_CHECK_FUNCS): Add `raise'.
|
||||
|
||||
* Makefile.in (inp.o): No longer depends on quotearg.h.
|
||||
|
||||
* common.h (outfile): New decl (was private var named `output').
|
||||
(invc): New decl.
|
||||
(GENERIC_OBJECT): Renamed from VOID.
|
||||
(NULL_DEVICE, TTY_DEVICE): New macros.
|
||||
|
||||
* patch.c (output): Remove; renamed to `outfile' and moved to common.h.
|
||||
(main): `failed' is count, not boolean.
|
||||
Say "Skipping patch." when deciding to skip patch.
|
||||
(get_some_switches): Set invc when setting inname.
|
||||
|
||||
* inp.c: Do not include <quotearg.h>.
|
||||
(SCCSPREFIX, GET, GET_LOCKED, SCCSDIFF1, SCCSDIFF2, SCCSDIFF3,
|
||||
RCSSUFFIX, CHECKOUT, CHECKOUT_LOCKED, RCSDIFF1, RCSDIFF2):
|
||||
Move to util.c.
|
||||
(get_input_file): Invoke new functions version_controller and
|
||||
version_get to simplify this code.
|
||||
(plan_b): "/dev/tty" -> NULL_DEVICE
|
||||
|
||||
* pch.h (pch_timestamp): New decl.
|
||||
* pch.c (p_timestamp): New var; takes over from global timestamp array.
|
||||
(pch_timestamp): New function to export p_timestamp.
|
||||
(there_is_another_patch): Use blander wording when you can't intuit
|
||||
the file name.
|
||||
Say "Skipping patch." when deciding to skip patch.
|
||||
(intuit_diff_type): Look for version-controlled but nonexistent files
|
||||
when intuiting file names; set invc accordingly.
|
||||
Ignore Index: line if either old or new line is present, and if
|
||||
POSIXLY_CORRECT is not set.
|
||||
(do_ed_script): Flush stdout before invoking popen, since it may
|
||||
send output to stdout.
|
||||
|
||||
* util.h (version_controller, version_get): New decls.
|
||||
* util.c: Include <quotearg.h> earlier.
|
||||
(raise): New macro, if ! HAVE_RAISE.
|
||||
(move_file): Create empty unreadable file when backing up a nonexistent
|
||||
file.
|
||||
(DEV_NULL): New constant.
|
||||
(SCCSPREFIX, GET. GET_LOCKED, SCCSDIFF1, SCCSDIFF2,
|
||||
RCSSUFFIX, CHECKOUT, CHECKOUT_LOCKED, RCSDIFF1): Moved here from inp.c.
|
||||
(version_controller, version_get): New functions.
|
||||
(ask): Look only at /dev/tty for answers; and when standard output is
|
||||
not a terminal and ! posixly_correct, don't even look there.
|
||||
Remove unnecessary fflushes of stdout.
|
||||
(ok_to_reverse): Say "Skipping patch." when deciding to skip patch..
|
||||
(sigs): SIGPIPE might not be defined.
|
||||
(exit_with_signal): Use `raise' instead of `kill'.
|
||||
(systemic): fflush stdout before invoking subsidiary command.
|
||||
|
||||
* patch.man: Document recent changes.
|
||||
Add "COMPATIBILITY ISSUES" section.
|
||||
|
||||
* NEWS: New COMPATIBILITY ISSUES for man page.
|
||||
Changed verbosity when fuzz is found.
|
||||
File name intuition is changed, again.
|
||||
Backups are made unreadable when the file did not exist.
|
||||
|
||||
* pc/djgpp/config.h (HAVE_STRUCT_UTIMBUF): Define.
|
||||
(HAVE_RAISE): New macro.
|
||||
(HAVE_UTIME_H): Define.
|
||||
(TZ_is_unset): Do not define; it's not a serious problem with `patch'
|
||||
to have TZ be unset in DOS.
|
||||
|
||||
1997-06-08 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION): Bump to 2.3.6.
|
||||
(AC_CHECK_HEADERS): Add utime.h.
|
||||
* acconfig.h, configure.in, pc/djgpp/config.h (HAVE_STRUCT_UTIMBUF):
|
||||
New macro.
|
||||
* pc/djgpp/config.h (HAVE_UTIME_H, TZ_is_unset): New macros.
|
||||
|
||||
* NEWS, patch.man: Describe new -Z, -T options, new numeric
|
||||
option for -G, retired -G, and more verbose default behavior
|
||||
with fuzz.
|
||||
|
||||
* pch.c (intuit_diff_type): Record times reported for files in headers.
|
||||
Remove head_says_nonexistent[x], since it's now equivalent to
|
||||
!timestamp[x].
|
||||
* util.h (fetchname): Change argument head_says_nonexistent to
|
||||
timestamp.
|
||||
* util.c: #include <partime.h> for TM_LOCAL_ZONE.
|
||||
Don't include <time.h> since common.h now includes it.
|
||||
(ok_to_reverse): noreverse and batch cases now output regardless of
|
||||
verbosity.
|
||||
(fetchname): Change argument head_says_nonexistent to pstamp, and
|
||||
store header timestamp into *pstamp.
|
||||
If -T or -Z option is given, match time stamps more precisely.
|
||||
(ask): Remove unnecessary close of ttyfd.
|
||||
When there is no terminal at all, output a newline to make the
|
||||
output look nicer. After reporting EOF, flush stdout;
|
||||
when an input error, report the error type.
|
||||
|
||||
* inp.c (get_input_file):
|
||||
Ask user whether to get file if patch_get is negative.
|
||||
|
||||
* Makefile.in (clean): Don't clean */*.o; clean core* and *core.
|
||||
|
||||
1997-06-04 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION): Bump to 2.3.5.
|
||||
|
||||
* util.c (ok_to_reverse):
|
||||
Be less chatty if verbosity is SILENT and we don't
|
||||
have to ask the user. If force is nonzero, apply the patch anyway.
|
||||
|
||||
* pch.c (there_is_another_patch):
|
||||
Before skipping rest of patch, skip to
|
||||
the patch start, so that another_hunk can skip it properly.
|
||||
(intuit_diff_type): Slight wording change for missing headers, to
|
||||
regularize with other diagnostics. Fix off-by-one error when setting
|
||||
p_input_line when scanning the first hunk to check for deleted files.
|
||||
|
||||
1997-06-03 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION): Bump to 2.3.4.
|
||||
|
||||
* NEWS: Now matches more generously against nonexistent or empty files.
|
||||
|
||||
* pch.c (there_is_another_patch): Move warning about not being
|
||||
able to intuit file names here from skip_to.
|
||||
(intuit_diff_type): Fatal error if we find a headless unified
|
||||
or context diff.
|
||||
|
||||
* util.c (ask): Null-terminate buffer properly even if it grew.
|
||||
(fetchname): No need to test for null first argument.
|
||||
|
||||
1997-06-02 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION): Bump to 2.3.3.
|
||||
* pch.c (p_says_nonexistent, pch_says_nonexistent): Is now 1 for empty,
|
||||
2 for nonexistent.
|
||||
(intuit_diff_type): Set p_says_nonexistent according to new meaning.
|
||||
Treat empty files like nonexistent files when reversing.
|
||||
(skip_to): Output better diagnostic when we can't intuit a file name.
|
||||
* patch.c (main):
|
||||
Count bytes, not lines, when testing whether a file is empty,
|
||||
since it may contain only non-newline chars.
|
||||
pch_says_nonexistent now returns 2 for nonexistent files.
|
||||
|
||||
1997-06-01 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION): Bump to 2.3.2.
|
||||
* pch.c (open_patch_file):
|
||||
Fix bug when computing size of patch read from a pipe.
|
||||
|
||||
1997-05-30 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION): Bump to 2.3.1.
|
||||
|
||||
* Makefile.in (transform, patch_name): New vars,
|
||||
for proper implementation of AC_ARG_PROGRAM.
|
||||
(install, uninstall): Use them.
|
||||
(install-strip): New rule.
|
||||
* pc/djgpp/config.sed (program_transform_name): Set to empty.
|
||||
|
||||
1997-05-30 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION), NEWS: Version 2.3 released.
|
||||
@ -88,50 +307,6 @@
|
||||
* Makefile.in (DISTFILES_PC): Remove pc/quotearg.c.
|
||||
* pc/djgpp/config.sed: Remove unnecessary hooks for quotearg and SHELL.
|
||||
|
||||
1997-05-18 Paul Eggert <eggert@pogo.gnu.ai.mit.edu>
|
||||
|
||||
* configure.in (VERSION): Increase to 2.2.9.
|
||||
(AC_TYPE_MODE_T): Add.
|
||||
|
||||
* pch.c (hunkmax): Now of type LINENUM.
|
||||
(malformed): Add decl.
|
||||
(there_is_another_patch): Skip inname-detection if skip_rest_of_patch.
|
||||
(intuit_diff_type): To determine whether file appears to have been
|
||||
deleted, look at replacement, not pattern.
|
||||
If there is a mismatch between existence of file and whether the
|
||||
patch claims to change whether the file exists, ask whether to
|
||||
reverse the patch.
|
||||
(another_hunk): New parameter REV specifying whether to reverse the
|
||||
hunk. All callers changed.
|
||||
(do_ed_script): Add assertion to ensure input file exists.
|
||||
|
||||
* common.h (noreverse): New decl.
|
||||
(ok_to_reverse): Remove decl.
|
||||
|
||||
* patch.c (noreverse): Now extern.
|
||||
(main): New environment var PATCH_VERSION_CONTROL overrides VERSION_CONTROL.
|
||||
Don't assert(hunk) if we're skipping the patch; we may not have any hunks.
|
||||
When removing a file, back it up if backups are desired.
|
||||
Don't chmod output file if input file did not exist.
|
||||
chmod rej file to input file's mode minus executable bits.
|
||||
(locate_hunk): Go back to old way of a single fuzz parameter, but
|
||||
handle it more precisely: context diffs with partial contexts
|
||||
can only match file ends, since the partial context can occur
|
||||
only at the start or end of file.
|
||||
All callers changed.
|
||||
(create_output_file): Use create_file to create files.
|
||||
(ok_to_reverse): Move to util.c.
|
||||
|
||||
* inp.c (scan_input, get_input_file): Quote file names in diagnostics.
|
||||
(get_input_file): Set inerrno if it's not already set.
|
||||
Don't create file; it's now the caller's responsibility.
|
||||
(plan_b): Use /dev/null if input size is zero, since it might not exist.
|
||||
Use create_file to create temporary file.
|
||||
|
||||
* NEWS: Add PATCH_VERSION_CONTROL; DOS port is untested.
|
||||
|
||||
* patch.man: PATCH_VERSION_CONTROL overrides VERSION_CONTROL.
|
||||
|
||||
1997-05-18 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* configure.in (VERSION): Increase to 2.2.9.
|
||||
|
||||
30
Makefile.in
30
Makefile.in
@ -28,6 +28,7 @@ ed_PROGRAM = @ed_PROGRAM@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
transform = @program_transform_name@
|
||||
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
@ -45,11 +46,10 @@ bindir = $(exec_prefix)/bin
|
||||
|
||||
# Where to put the manual pages.
|
||||
man1dir = $(prefix)/man/man1
|
||||
# Extension (not including `.') for the manual page filenames.
|
||||
# Extension (including `.') for the manual page filenames.
|
||||
man1ext = .1
|
||||
|
||||
# Hooks for nonstandard builds.
|
||||
CONFIG_HDRS = config.h
|
||||
# Hook for nonstandard builds.
|
||||
CONFIG_STATUS = config.status
|
||||
|
||||
#### End of system configuration section. ####
|
||||
@ -68,8 +68,10 @@ MISC = COPYING ChangeLog INSTALL Makefile.in NEWS README \
|
||||
install-sh mkinstalldirs patch.man
|
||||
DISTFILES = $(MISC) $(SRCS) $(HDRS)
|
||||
DISTFILES_PC = pc/chdirsaf.c
|
||||
DISTFILES_PC_DJGPP = pc/djgpp/README pc/djgpp/config.h \
|
||||
pc/djgpp/config.sed pc/djgpp/configure.bat
|
||||
DISTFILES_PC_DJGPP = pc/djgpp/README pc/djgpp/config.sed \
|
||||
pc/djgpp/configure.bat pc/djgpp/configure.sed
|
||||
|
||||
patch_name = `echo patch | sed '$(transform)'`
|
||||
|
||||
all:: patch
|
||||
|
||||
@ -87,15 +89,17 @@ patch: $(OBJS)
|
||||
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS)
|
||||
|
||||
install:: all installdirs
|
||||
$(INSTALL_PROGRAM) patch $(bindir)/`echo patch | sed '$(transform)'`
|
||||
-$(INSTALL_DATA) $(srcdir)/patch.man \
|
||||
$(man1dir)/`echo patch | sed '$(transform)'`$(man1ext)
|
||||
$(INSTALL_PROGRAM) patch $(bindir)/$(patch_name)
|
||||
-$(INSTALL_DATA) $(srcdir)/patch.man $(man1dir)/$(patch_name)$(man1ext)
|
||||
|
||||
installdirs::
|
||||
$(SHELL) $(srcdir)/mkinstalldirs $(bindir) $(man1dir)
|
||||
|
||||
install-strip::
|
||||
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
|
||||
|
||||
uninstall::
|
||||
rm -f $(bindir)/patch $(man1dir)/patch$(man1ext)
|
||||
rm -f $(bindir)/$(patch_name) $(man1dir)/$(patch_name)$(man1ext)
|
||||
|
||||
Makefile: Makefile.in $(CONFIG_STATUS)
|
||||
$(SHELL) $(CONFIG_STATUS)
|
||||
@ -113,7 +117,7 @@ TAGS: $(HDRS) patchlevel.h $(SRCS)
|
||||
etags $(HDRS) patchlevel.h $(SRCS)
|
||||
|
||||
clean::
|
||||
rm -f patch *.o */*.o core
|
||||
rm -f patch core* *core *.o
|
||||
|
||||
mostlyclean:: clean
|
||||
|
||||
@ -138,17 +142,17 @@ dist:: $(DISTFILES) $(DISTFILES_PC) $(DISTFILES_PC_DJGPP)
|
||||
tar -chf - $(PV) | gzip -9 >$(PV).tar.gz
|
||||
rm -rf $(PV)
|
||||
|
||||
$(OBJS): $(CONFIG_HDRS)
|
||||
$(OBJS): config.h
|
||||
addext.o: backupfile.h
|
||||
argmatch.o: argmatch.h
|
||||
backupfile.o: argmatch.h backupfile.h
|
||||
basename.o: backupfile.h
|
||||
getopt.o getopt1.o: getopt.h
|
||||
maketime.o: maketime.h partime.h
|
||||
inp.o: backupfile.h common.h inp.h pch.h quotearg.h util.h
|
||||
inp.o: backupfile.h common.h inp.h pch.h util.h
|
||||
partime.o: partime.h
|
||||
patch.o: argmatch.h backupfile.h common.h getopt.h inp.h pch.h util.h version.h
|
||||
pch.o: common.h inp.h pch.h util.h
|
||||
quotearg.o: quotearg.h
|
||||
util.o: backupfile.h common.h maketime.h quotearg.h util.h version.h
|
||||
util.o: backupfile.h common.h maketime.h partime.h quotearg.h util.h version.h
|
||||
version.o: common.h patchlevel.h util.h version.h
|
||||
|
||||
72
NEWS
72
NEWS
@ -3,6 +3,46 @@ Known problems:
|
||||
* The diffutils 2.7 documentation for `patch' is obsolete; this should be
|
||||
fixed in diffutils 2.8. Until then, see `patch --help' or `man patch'.
|
||||
|
||||
Change in version 2.4:
|
||||
|
||||
* New options:
|
||||
-Z or --set-utc sets times of patched files, assuming diff uses UTC (GMT).
|
||||
-T or --set-time is similar, assuming local time (not recommended).
|
||||
--backup-if-mismatch makes a backup if the patch does not match exactly
|
||||
--no-backup-if-mismatch makes a backup only if otherwise requested
|
||||
|
||||
* The default is now --backup-if-mismatch unless POSIXLY_CORRECT is set.
|
||||
|
||||
* The -B or --prefix, -Y or --basename-prefix, and -z or --suffix options
|
||||
no longer affect whether backups are made (as they did in patch 2.2 and 2.3);
|
||||
they now merely specify the file names used when simple backups are made.
|
||||
|
||||
* When patching a nonexistent file and making backups, an empty backup file
|
||||
is now made (just as with traditional patch); but the backup file is
|
||||
unreadable, as a way of indicating that it represents a nonexistent file.
|
||||
|
||||
* `patch' now matches against empty and nonexistent files more generously.
|
||||
A patch against an empty file applies to a nonexistent file, and vice versa.
|
||||
|
||||
* -g or --get and PATCH_GET now have a numeric value that specifies
|
||||
whether `patch' is getting files.
|
||||
If the value is positive, working files are gotten from RCS or SCCS files;
|
||||
if zero, `patch' ignores RCS and SCCS and working files are not gotten;
|
||||
and if negative, `patch' asks the user whether to get each file.
|
||||
The default is normally negative, but it is zero if POSIXLY_CORRECT is set.
|
||||
|
||||
* The -G or --no-get option introduced in GNU patch 2.3 has been removed;
|
||||
use -g0 instead.
|
||||
|
||||
* The method used to intuit names of files to be patched is changed again:
|
||||
`Index:' lines are normally ignored for context diffs,
|
||||
and RCS and SCCS files are normally looked for when files do not exist.
|
||||
The complete new method is described in the man page.
|
||||
|
||||
* By default, `patch' is now more verbose when patches do not match exactly.
|
||||
|
||||
* The manual page has a new COMPATIBILITY ISSUES section.
|
||||
|
||||
Changes in version 2.3:
|
||||
|
||||
* Unless the POSIXLY_CORRECT environment variable is set:
|
||||
@ -11,35 +51,19 @@ Changes in version 2.3:
|
||||
nonexistent files if the input is a context diff.
|
||||
A file is assumed to not exist if its context diff header
|
||||
suggests that it is empty, and if the header timestamp
|
||||
is within 24 hours of 1970-01-01 00:00:00 UTC.
|
||||
looks like it might be equivalent to 1970-01-01 00:00:00 UTC.
|
||||
- Files that ``become nonexistent'' after patching are now removed.
|
||||
When a file is removed, any empty ancestor directories are also removed.
|
||||
|
||||
* Files are now automatically gotten from RCS and SCCS
|
||||
if the -g or --get option is specified,
|
||||
or if the PATCH_GET environment variable is set
|
||||
and the -G or --no-get option is not specified.
|
||||
if the -g or --get option is specified.
|
||||
(The -G or --no-get option, also introduced in 2.3, was withdrawn in 2.4.)
|
||||
|
||||
* If the PATCH_VERSION_CONTROL environment variable is set,
|
||||
it overrides the VERSION_CONTROL environment variable.
|
||||
|
||||
* The method used to intuit names of files to be patched is now as follows:
|
||||
|
||||
- Take the old and new names from the context header if present,
|
||||
and take the index name from the `Index:' line if present.
|
||||
Consider the file names to be in the order (old, new, index).
|
||||
- If some named files exist, use the first one if POSIXLY_CORRECT is set,
|
||||
the best one otherwise.
|
||||
- If no named files exist, some names are given, POSIXLY_CORRECT is not set,
|
||||
and the patch appears to create a file, then use the best name
|
||||
requiring the creation of the fewest directories.
|
||||
- Otherwise, ask the user for a file name.
|
||||
|
||||
The ``best'' of a nonempty list of file names is defined as follows:
|
||||
- Take the names with the fewest path name components;
|
||||
of those, take the names with the shortest basename;
|
||||
of those, take the shortest names;
|
||||
of those, take the first name.
|
||||
* The method used to intuit names of files to be patched is changed.
|
||||
(It was further revised in 2.4; see above.)
|
||||
|
||||
* The new --binary option makes `patch' read and write files in binary mode.
|
||||
This option has no effect on POSIX-compliant hosts;
|
||||
@ -73,8 +97,8 @@ Changes in version 2.2:
|
||||
* Patch now complies better with POSIX.2 if your host complies with POSIX.1.
|
||||
|
||||
Therefore:
|
||||
- By default, no backups are made. Set the VERSION_CONTROL environment
|
||||
variable to "existing" if you prefer patch's traditional behavior.
|
||||
- By default, no backups are made.
|
||||
(But this was changed again in patch 2.4; see above.)
|
||||
- The simple backup file name for F defaults to F.orig
|
||||
regardless of whether the file system supports long file names,
|
||||
and F~ is used only if F.orig is too long for that particular file.
|
||||
@ -89,6 +113,7 @@ Changes in version 2.2:
|
||||
consulted if none of the above files exist. However, if the patch
|
||||
appears to create a file, the file does not have to exist: instead,
|
||||
the first name with the longest existing directory prefix is taken.
|
||||
(These rules were changed again in patch 2.3 and 2.4; see above.)
|
||||
- Exit status 0 means success, 1 means hunks were rejected, 2 means trouble.
|
||||
- `-l' ignores changes only in spaces and tabs, not in other white space.
|
||||
- If no `-p' option is given, `-pINFINITY' is assumed, instead of trying
|
||||
@ -107,6 +132,7 @@ Changes in version 2.2:
|
||||
|
||||
* RCS is used only if the version control method is `existing'
|
||||
and there is already an RCS file. Similarly for SCCS.
|
||||
(But this was changed again in patch 2.3 and 2.4; see above.)
|
||||
|
||||
* Copyright notices have been clarified. Every file in this version of `patch'
|
||||
can be distributed under the GNU General Public License. See README for
|
||||
|
||||
@ -9,3 +9,6 @@
|
||||
|
||||
/* Define if memchr works. */
|
||||
#undef HAVE_MEMCHR
|
||||
|
||||
/* Define if `struct utimbuf' is declared -- usually in <utime.h>. */
|
||||
#undef HAVE_STRUCT_UTIMBUF
|
||||
|
||||
@ -109,8 +109,7 @@ static int version_number __BACKUPFILE_P ((const char *, const char *, size_t));
|
||||
|
||||
/* Return the name of the new backup file for file FILE,
|
||||
allocated with malloc. Return 0 if out of memory.
|
||||
FILE must not end with a '/' unless it is the root directory.
|
||||
Do not call this function if backup_type == none. */
|
||||
FILE must not end with a '/' unless it is the root directory. */
|
||||
|
||||
char *
|
||||
find_backup_file_name (file)
|
||||
@ -133,7 +132,7 @@ find_backup_file_name (file)
|
||||
strcpy (s, file);
|
||||
|
||||
#if HAVE_DIR
|
||||
if (backup_type != simple)
|
||||
if (backup_type != simple && backup_type != none)
|
||||
{
|
||||
int highest_backup;
|
||||
size_t dir_len = base_name (s) - s;
|
||||
|
||||
27
common.h
27
common.h
@ -1,6 +1,6 @@
|
||||
/* common definitions for `patch' */
|
||||
|
||||
/* $Id: common.h,v 1.16 1997/05/26 05:34:43 eggert Exp $ */
|
||||
/* $Id: common.h,v 1.18 1997/06/13 06:28:37 eggert Exp $ */
|
||||
|
||||
/*
|
||||
Copyright 1986, 1988 Larry Wall
|
||||
@ -44,6 +44,7 @@ If not, write to the Free Software Foundation,
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#if ! defined S_ISDIR && defined S_IFDIR
|
||||
@ -148,7 +149,9 @@ XTERN size_t bufsize; /* allocated size of buf */
|
||||
XTERN bool using_plan_a; /* try to keep everything in memory */
|
||||
|
||||
XTERN char *inname;
|
||||
XTERN char *outfile;
|
||||
XTERN int inerrno;
|
||||
XTERN int invc;
|
||||
XTERN struct stat instat;
|
||||
XTERN bool dry_run;
|
||||
XTERN bool posixly_correct;
|
||||
@ -174,6 +177,8 @@ XTERN bool skip_rest_of_patch;
|
||||
XTERN int strippath;
|
||||
XTERN bool canonicalize;
|
||||
XTERN int patch_get;
|
||||
XTERN int set_time;
|
||||
XTERN int set_utc;
|
||||
|
||||
enum diff
|
||||
{
|
||||
@ -190,9 +195,9 @@ XTERN enum diff diff_type;
|
||||
XTERN char *revision; /* prerequisite revision, if any */
|
||||
|
||||
#ifdef __STDC__
|
||||
# define VOID void
|
||||
# define GENERIC_OBJECT void
|
||||
#else
|
||||
# define VOID char
|
||||
# define GENERIC_OBJECT char
|
||||
#endif
|
||||
|
||||
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__
|
||||
@ -207,7 +212,7 @@ XTERN char *revision; /* prerequisite revision, if any */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
VOID *xmalloc PARAMS ((size_t));
|
||||
GENERIC_OBJECT *xmalloc PARAMS ((size_t));
|
||||
void fatal_exit PARAMS ((int)) __attribute__ ((noreturn));
|
||||
|
||||
#include <errno.h>
|
||||
@ -221,7 +226,7 @@ extern int errno;
|
||||
# if !HAVE_MEMCHR
|
||||
# define memcmp(s1, s2, n) bcmp (s1, s2, n)
|
||||
# define memcpy(d, s, n) bcopy (s, d, n)
|
||||
VOID *memchr ();
|
||||
GENERIC_OBJECT *memchr ();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -230,8 +235,8 @@ VOID *memchr ();
|
||||
#else
|
||||
long atol ();
|
||||
char *getenv ();
|
||||
VOID *malloc ();
|
||||
VOID *realloc ();
|
||||
GENERIC_OBJECT *malloc ();
|
||||
GENERIC_OBJECT *realloc ();
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
@ -292,3 +297,11 @@ off_t lseek ();
|
||||
#else
|
||||
# define binary_transput 0
|
||||
#endif
|
||||
|
||||
#ifndef NULL_DEVICE
|
||||
#define NULL_DEVICE "/dev/null"
|
||||
#endif
|
||||
|
||||
#ifndef TTY_DEVICE
|
||||
#define TTY_DEVICE "/dev/tty"
|
||||
#endif
|
||||
|
||||
@ -54,6 +54,9 @@
|
||||
/* Define if memchr works. */
|
||||
#undef HAVE_MEMCHR
|
||||
|
||||
/* Define if `struct utimbuf' is declared -- usually in <utime.h>. */
|
||||
#undef HAVE_STRUCT_UTIMBUF
|
||||
|
||||
/* Define if you have the _doprintf function. */
|
||||
#undef HAVE__DOPRINTF
|
||||
|
||||
@ -75,6 +78,9 @@
|
||||
/* Define if you have the pathconf function. */
|
||||
#undef HAVE_PATHCONF
|
||||
|
||||
/* Define if you have the raise function. */
|
||||
#undef HAVE_RAISE
|
||||
|
||||
/* Define if you have the rename function. */
|
||||
#undef HAVE_RENAME
|
||||
|
||||
@ -111,5 +117,8 @@
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
/* Define if you have the <varargs.h> header file. */
|
||||
#undef HAVE_VARARGS_H
|
||||
|
||||
92
configure
vendored
92
configure
vendored
@ -540,7 +540,7 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x,"
|
||||
|
||||
|
||||
PACKAGE=patch
|
||||
VERSION=2.3
|
||||
VERSION=2.4
|
||||
|
||||
|
||||
|
||||
@ -1349,7 +1349,7 @@ EOF
|
||||
|
||||
fi
|
||||
|
||||
for ac_hdr in fcntl.h limits.h string.h unistd.h varargs.h
|
||||
for ac_hdr in fcntl.h limits.h string.h unistd.h utime.h varargs.h
|
||||
do
|
||||
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
||||
@ -1531,9 +1531,45 @@ EOF
|
||||
fi
|
||||
|
||||
|
||||
echo $ac_n "checking for struct utimbuf""... $ac_c" 1>&6
|
||||
echo "configure:1536: checking for struct utimbuf" >&5
|
||||
if eval "test \"`echo '$''{'patch_cv_sys_struct_utimbuf'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1541 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
#if HAVE_UTIME_H
|
||||
#include <utime.h>
|
||||
#endif
|
||||
int main() {
|
||||
static struct utimbuf x; x.actime = x.modtime;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1551: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
patch_cv_sys_struct_utimbuf=yes
|
||||
else
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -rf conftest*
|
||||
patch_cv_sys_struct_utimbuf=no
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
|
||||
echo "$ac_t""$patch_cv_sys_struct_utimbuf" 1>&6
|
||||
if test $patch_cv_sys_struct_utimbuf = yes; then
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define HAVE_STRUCT_UTIMBUF 1
|
||||
EOF
|
||||
|
||||
fi
|
||||
|
||||
# Check for NetBSD 1.0 bug, where memchr(..., 0) returns nonzero.
|
||||
echo $ac_n "checking for working memchr""... $ac_c" 1>&6
|
||||
echo "configure:1537: checking for working memchr" >&5
|
||||
echo "configure:1573: checking for working memchr" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_memchr'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1542,12 +1578,12 @@ else
|
||||
ac_cv_func_memchr=no
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1546 "configure"
|
||||
#line 1582 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <string.h>
|
||||
main () { exit (memchr ("", 0, 0) != 0 || memchr ("", 1, 0) != 0); }
|
||||
EOF
|
||||
if { (eval echo configure:1551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
|
||||
if { (eval echo configure:1587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
ac_cv_func_memchr=yes
|
||||
else
|
||||
@ -1569,12 +1605,12 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for getopt_long""... $ac_c" 1>&6
|
||||
echo "configure:1573: checking for getopt_long" >&5
|
||||
echo "configure:1609: checking for getopt_long" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_getopt_long'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1578 "configure"
|
||||
#line 1614 "configure"
|
||||
#include "confdefs.h"
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char getopt_long(); below. */
|
||||
@ -1597,7 +1633,7 @@ getopt_long();
|
||||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1601: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:1637: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func_getopt_long=yes"
|
||||
else
|
||||
@ -1618,15 +1654,15 @@ LIBOBJS="$LIBOBJS getopt1.o getopt.o"
|
||||
fi
|
||||
|
||||
|
||||
for ac_func in _doprintf isascii memcmp mkdir mktemp pathconf sigaction sigprocmask sigsetmask
|
||||
for ac_func in _doprintf isascii memcmp mkdir mktemp pathconf raise sigaction sigprocmask sigsetmask
|
||||
do
|
||||
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
|
||||
echo "configure:1625: checking for $ac_func" >&5
|
||||
echo "configure:1661: checking for $ac_func" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1630 "configure"
|
||||
#line 1666 "configure"
|
||||
#include "confdefs.h"
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func(); below. */
|
||||
@ -1649,7 +1685,7 @@ $ac_func();
|
||||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:1689: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func_$ac_func=yes"
|
||||
else
|
||||
@ -1676,12 +1712,12 @@ done
|
||||
for ac_func in memchr rename
|
||||
do
|
||||
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
|
||||
echo "configure:1680: checking for $ac_func" >&5
|
||||
echo "configure:1716: checking for $ac_func" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1685 "configure"
|
||||
#line 1721 "configure"
|
||||
#include "confdefs.h"
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func(); below. */
|
||||
@ -1704,7 +1740,7 @@ $ac_func();
|
||||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1708: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:1744: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func_$ac_func=yes"
|
||||
else
|
||||
@ -1731,7 +1767,7 @@ done
|
||||
|
||||
|
||||
echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6
|
||||
echo "configure:1735: checking whether closedir returns void" >&5
|
||||
echo "configure:1771: checking whether closedir returns void" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_closedir_void'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1739,13 +1775,13 @@ else
|
||||
ac_cv_func_closedir_void=yes
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1743 "configure"
|
||||
#line 1779 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
#include <$ac_header_dirent>
|
||||
int closedir(); main() { exit(closedir(opendir(".")) != 0); }
|
||||
EOF
|
||||
if { (eval echo configure:1749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
|
||||
if { (eval echo configure:1785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
ac_cv_func_closedir_void=no
|
||||
else
|
||||
@ -1768,12 +1804,12 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for vprintf""... $ac_c" 1>&6
|
||||
echo "configure:1772: checking for vprintf" >&5
|
||||
echo "configure:1808: checking for vprintf" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1777 "configure"
|
||||
#line 1813 "configure"
|
||||
#include "confdefs.h"
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char vprintf(); below. */
|
||||
@ -1796,7 +1832,7 @@ vprintf();
|
||||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1800: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:1836: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func_vprintf=yes"
|
||||
else
|
||||
@ -1820,12 +1856,12 @@ fi
|
||||
|
||||
if test "$ac_cv_func_vprintf" != yes; then
|
||||
echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
|
||||
echo "configure:1824: checking for _doprnt" >&5
|
||||
echo "configure:1860: checking for _doprnt" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1829 "configure"
|
||||
#line 1865 "configure"
|
||||
#include "confdefs.h"
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char _doprnt(); below. */
|
||||
@ -1848,7 +1884,7 @@ _doprnt();
|
||||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:1888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func__doprnt=yes"
|
||||
else
|
||||
@ -1874,7 +1910,7 @@ fi
|
||||
|
||||
|
||||
echo $ac_n "checking for long file names""... $ac_c" 1>&6
|
||||
echo "configure:1878: checking for long file names" >&5
|
||||
echo "configure:1914: checking for long file names" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_sys_long_file_names'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1919,12 +1955,12 @@ fi
|
||||
|
||||
|
||||
echo $ac_n "checking for d_ino member in directory struct""... $ac_c" 1>&6
|
||||
echo "configure:1923: checking for d_ino member in directory struct" >&5
|
||||
echo "configure:1959: checking for d_ino member in directory struct" >&5
|
||||
if eval "test \"`echo '$''{'patch_cv_sys_d_ino_in_dirent'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1928 "configure"
|
||||
#line 1964 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -1947,7 +1983,7 @@ int main() {
|
||||
struct dirent dp; dp.d_ino = 0;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:1987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
rm -rf conftest*
|
||||
patch_cv_sys_d_ino_in_dirent=yes
|
||||
else
|
||||
|
||||
20
configure.in
20
configure.in
@ -8,7 +8,7 @@ AC_CONFIG_HEADER(config.h:config.hin)
|
||||
AC_ARG_PROGRAM
|
||||
|
||||
PACKAGE=patch
|
||||
VERSION=2.3
|
||||
VERSION=2.4
|
||||
AC_SUBST(PACKAGE)
|
||||
AC_SUBST(VERSION)
|
||||
|
||||
@ -60,13 +60,27 @@ AC_C_CONST
|
||||
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(fcntl.h limits.h string.h unistd.h varargs.h)
|
||||
AC_CHECK_HEADERS(fcntl.h limits.h string.h unistd.h utime.h varargs.h)
|
||||
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_SIGNAL
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
dnl Some systems have utime.h but don't declare the struct anywhere.
|
||||
AC_MSG_CHECKING(for struct utimbuf)
|
||||
AC_CACHE_VAL(patch_cv_sys_struct_utimbuf,
|
||||
[AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#if HAVE_UTIME_H
|
||||
#include <utime.h>
|
||||
#endif], [static struct utimbuf x; x.actime = x.modtime;],
|
||||
patch_cv_sys_struct_utimbuf=yes,
|
||||
patch_cv_sys_struct_utimbuf=no)])
|
||||
AC_MSG_RESULT($patch_cv_sys_struct_utimbuf)
|
||||
if test $patch_cv_sys_struct_utimbuf = yes; then
|
||||
AC_DEFINE(HAVE_STRUCT_UTIMBUF)
|
||||
fi
|
||||
|
||||
# Check for NetBSD 1.0 bug, where memchr(..., 0) returns nonzero.
|
||||
AC_MSG_CHECKING(for working memchr)
|
||||
AC_CACHE_VAL(ac_cv_func_memchr,
|
||||
@ -83,7 +97,7 @@ fi
|
||||
|
||||
AC_CHECK_FUNC(getopt_long, , [LIBOBJS="$LIBOBJS getopt1.o getopt.o"])
|
||||
AC_SUBST(LIBOBJS)
|
||||
AC_CHECK_FUNCS(_doprintf isascii memcmp mkdir mktemp pathconf sigaction sigprocmask sigsetmask)
|
||||
AC_CHECK_FUNCS(_doprintf isascii memcmp mkdir mktemp pathconf raise sigaction sigprocmask sigsetmask)
|
||||
AC_REPLACE_FUNCS(memchr rename)
|
||||
AC_FUNC_CLOSEDIR_VOID
|
||||
AC_FUNC_VPRINTF
|
||||
|
||||
134
inp.c
134
inp.c
@ -1,6 +1,6 @@
|
||||
/* inputting files to be patched */
|
||||
|
||||
/* $Id: inp.c,v 1.14 1997/05/26 05:34:43 eggert Exp $ */
|
||||
/* $Id: inp.c,v 1.16 1997/06/13 06:28:37 eggert Exp $ */
|
||||
|
||||
/*
|
||||
Copyright 1986, 1988 Larry Wall
|
||||
@ -26,25 +26,11 @@ If not, write to the Free Software Foundation,
|
||||
#include <common.h>
|
||||
#include <backupfile.h>
|
||||
#include <pch.h>
|
||||
#include <quotearg.h>
|
||||
#include <util.h>
|
||||
#undef XTERN
|
||||
#define XTERN
|
||||
#include <inp.h>
|
||||
|
||||
static char const SCCSPREFIX[] = "s.";
|
||||
static char const GET[] = "get ";
|
||||
static char const GET_LOCKED[] = "get -e ";
|
||||
static char const SCCSDIFF1[] = "get -p ";
|
||||
static char const SCCSDIFF2[] = "|diff - %s";
|
||||
static char const SCCSDIFF3[] = ">/dev/null";
|
||||
|
||||
static char const RCSSUFFIX[] = ",v";
|
||||
static char const CHECKOUT[] = "co %s";
|
||||
static char const CHECKOUT_LOCKED[] = "co -l %s";
|
||||
static char const RCSDIFF1[] = "rcsdiff %s";
|
||||
#define RCSDIFF2 SCCSDIFF3
|
||||
|
||||
/* Input-file-with-indexable-lines abstract type */
|
||||
|
||||
static char const **i_ptr; /* pointers to lines in plan A buffer */
|
||||
@ -148,92 +134,28 @@ get_input_file (filename, outname)
|
||||
char const *outname;
|
||||
{
|
||||
int elsewhere = strcmp (filename, outname);
|
||||
char const *cs;
|
||||
char *diffbuf;
|
||||
char *getbuf;
|
||||
|
||||
if (inerrno == -1)
|
||||
inerrno = stat (inname, &instat) == 0 ? 0 : errno;
|
||||
|
||||
/* Perhaps look for RCS or SCCS versions. */
|
||||
if (patch_get
|
||||
&& invc != 0
|
||||
&& (inerrno
|
||||
|| (! elsewhere
|
||||
&& (/* No one can write to it. */
|
||||
(instat.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) == 0
|
||||
/* Only the owner (who's not me) can write to it. */
|
||||
|| ((instat.st_mode & (S_IWGRP|S_IWOTH)) == 0
|
||||
&& instat.st_uid != geteuid ()))))) {
|
||||
struct stat cstat;
|
||||
char const *cs = 0;
|
||||
char const *filebase = base_name (filename);
|
||||
char const *dotslash = *filename=='-' ? "./" : "";
|
||||
size_t dir_len = filebase - filename;
|
||||
size_t filenamelen = strlen (filename);
|
||||
size_t maxfixlen = sizeof "SCCS/" - 1 + sizeof SCCSPREFIX - 1;
|
||||
size_t maxtrysize = filenamelen + maxfixlen + 1;
|
||||
size_t quotelen = quote_system_arg (0, filename);
|
||||
size_t maxgetsize = sizeof GET_LOCKED + quotelen + maxfixlen;
|
||||
size_t maxdiffsize =
|
||||
(sizeof SCCSDIFF1 + sizeof SCCSDIFF2 + sizeof SCCSDIFF3 - 2
|
||||
+ 2 * quotelen + maxfixlen);
|
||||
char *trybuf = xmalloc (maxtrysize + maxgetsize + maxdiffsize);
|
||||
char *getbuf = trybuf + maxtrysize;
|
||||
char *diffbuf = getbuf + maxgetsize;
|
||||
&& instat.st_uid != geteuid ()))))
|
||||
&& (invc = !! (cs = (version_controller
|
||||
(filename, elsewhere,
|
||||
inerrno ? (struct stat *) 0 : &instat,
|
||||
&getbuf, &diffbuf))))) {
|
||||
|
||||
strcpy (trybuf, filename);
|
||||
|
||||
#define try1(f,a1) (sprintf (trybuf + dir_len, f, a1), stat (trybuf, &cstat) == 0)
|
||||
#define try2(f,a1,a2) (sprintf (trybuf + dir_len, f, a1,a2), stat (trybuf, &cstat) == 0)
|
||||
if (( try2 ("RCS/%s%s", filebase, RCSSUFFIX)
|
||||
|| try1 ("RCS/%s" , filebase)
|
||||
|| try2 ( "%s%s", filebase, RCSSUFFIX))
|
||||
&&
|
||||
/* Check that RCS file is not working file.
|
||||
Some hosts don't report file name length errors. */
|
||||
(inerrno
|
||||
|| instat.st_dev != cstat.st_dev
|
||||
|| instat.st_ino != cstat.st_ino)) {
|
||||
|
||||
char *p = getbuf;
|
||||
sprintf (p, elsewhere ? CHECKOUT : CHECKOUT_LOCKED, dotslash);
|
||||
p += strlen (p);
|
||||
p += quote_system_arg (p, filename);
|
||||
*p = '\0';
|
||||
|
||||
p = diffbuf;
|
||||
sprintf (p, RCSDIFF1, dotslash);
|
||||
p += strlen (p);
|
||||
p += quote_system_arg (p, filename);
|
||||
strcpy (p, RCSDIFF2);
|
||||
|
||||
cs = "RCS";
|
||||
|
||||
} else if ( try2 ("SCCS/%s%s", SCCSPREFIX, filebase)
|
||||
|| try2 ( "%s%s", SCCSPREFIX, filebase)) {
|
||||
|
||||
char *p = getbuf;
|
||||
sprintf (p, elsewhere ? GET : GET_LOCKED);
|
||||
p += strlen (p);
|
||||
p += quote_system_arg (p, trybuf);
|
||||
*p = '\0';
|
||||
|
||||
p = diffbuf;
|
||||
strcpy (p, SCCSDIFF1);
|
||||
p += sizeof SCCSDIFF1 - 1;
|
||||
p += quote_system_arg (p, trybuf);
|
||||
sprintf (p, SCCSDIFF2, dotslash);
|
||||
p += strlen (p);
|
||||
p += quote_system_arg (p, filename);
|
||||
strcpy (p, SCCSDIFF3);
|
||||
|
||||
cs = "SCCS";
|
||||
|
||||
} else if (inerrno && !pch_says_nonexistent (reverse))
|
||||
{
|
||||
errno = inerrno;
|
||||
pfatal ("can't find file `%s'", filename);
|
||||
}
|
||||
/* else we can't write to it but it's not under a version
|
||||
control system, so just proceed. */
|
||||
if (cs) {
|
||||
if (!inerrno) {
|
||||
if (!elsewhere
|
||||
&& (instat.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) != 0)
|
||||
@ -252,27 +174,19 @@ get_input_file (filename, outname)
|
||||
cs = 0;
|
||||
}
|
||||
}
|
||||
if (cs)
|
||||
{
|
||||
if (dry_run)
|
||||
{
|
||||
if (inerrno)
|
||||
fatal ("can't do dry run on nonexistent version-controlled file `%s'; invoke `%s' and try again",
|
||||
filename, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbosity == VERBOSE)
|
||||
say ("Getting file `%s' from %s...\n", filename, cs);
|
||||
if (systemic (getbuf) != 0
|
||||
|| stat (filename, &instat) != 0)
|
||||
fatal ("can't get file `%s' from %s", filename, cs);
|
||||
inerrno = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
free (trybuf);
|
||||
}
|
||||
|
||||
if (cs && version_get (filename, cs, ! inerrno, elsewhere, getbuf,
|
||||
&instat))
|
||||
inerrno = 0;
|
||||
|
||||
free (getbuf);
|
||||
free (diffbuf);
|
||||
|
||||
} else if (inerrno && !pch_says_nonexistent (reverse))
|
||||
{
|
||||
errno = inerrno;
|
||||
pfatal ("can't find file `%s'", filename);
|
||||
}
|
||||
|
||||
if (inerrno)
|
||||
{
|
||||
@ -397,7 +311,7 @@ plan_b(filename)
|
||||
register LINENUM line;
|
||||
|
||||
if (instat.st_size == 0)
|
||||
filename = "/dev/null";
|
||||
filename = NULL_DEVICE;
|
||||
if (! (ifp = fopen (filename, binary_transput ? "rb" : "r")))
|
||||
pfatal ("can't open file `%s'", filename);
|
||||
tifd = create_file (TMPINNAME, O_RDWR | O_BINARY, (mode_t) 0);
|
||||
|
||||
11
maketime.c
11
maketime.c
@ -36,6 +36,8 @@
|
||||
# define const
|
||||
# endif
|
||||
# endif
|
||||
/* MIPS RISCOS4.52 defines time_t in <sys/types.h> not <time.h>. */
|
||||
# include <sys/types.h>
|
||||
# if HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
# endif
|
||||
@ -57,7 +59,7 @@
|
||||
#include <maketime.h>
|
||||
|
||||
char const maketId[] =
|
||||
"$Id: maketime.c,v 5.13 1997/05/15 17:33:14 eggert Exp $";
|
||||
"$Id: maketime.c,v 5.15 1997/06/17 16:54:36 eggert Exp $";
|
||||
|
||||
static int isleap P ((int));
|
||||
static int month_days P ((struct tm const *));
|
||||
@ -101,10 +103,10 @@ time2tm (unixtime, localzone)
|
||||
int localzone;
|
||||
{
|
||||
struct tm *tm;
|
||||
#if TZ_must_be_set
|
||||
#ifdef TZ_is_unset
|
||||
static char const *TZ;
|
||||
if (!TZ && !(TZ = getenv ("TZ")))
|
||||
faterror ("The TZ environment variable is not set; please set it to your timezone");
|
||||
TZ_is_unset ("The TZ environment variable is not set; please set it to your timezone");
|
||||
#endif
|
||||
if (localzone || !(tm = gmtime (&unixtime)))
|
||||
tm = localtime (&unixtime);
|
||||
@ -114,7 +116,8 @@ time2tm (unixtime, localzone)
|
||||
/* Yield A - B, measured in seconds. */
|
||||
time_t
|
||||
difftm (a, b)
|
||||
struct tm const *a, *b;
|
||||
struct tm const *a;
|
||||
struct tm const *b;
|
||||
{
|
||||
int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
|
||||
int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
|
||||
|
||||
330
patch.c
330
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;
|
||||
|
||||
507
patch.man
507
patch.man
@ -2,7 +2,7 @@
|
||||
.de Id
|
||||
.ds Dt \\$4
|
||||
..
|
||||
.Id $Id: patch.man,v 1.16 1997/05/30 08:03:48 eggert Exp $
|
||||
.Id $Id: patch.man,v 1.20 1997/06/17 22:32:49 eggert Exp $
|
||||
.ds = \-\^\-
|
||||
.de Sp
|
||||
.if t .sp .3
|
||||
@ -20,7 +20,7 @@ patch \- apply a diff file to an original
|
||||
.Sp
|
||||
but usually just
|
||||
.Sp
|
||||
.BI "patch \-p" "number"
|
||||
.BI "patch \-p" "num"
|
||||
.BI < patchfile
|
||||
.SH DESCRIPTION
|
||||
.B patch
|
||||
@ -115,9 +115,6 @@ As each hunk is completed, you are told if the hunk
|
||||
failed, and if so which line (in the new file)
|
||||
.B patch
|
||||
thought the hunk should go on.
|
||||
If the
|
||||
.B \*=verbose
|
||||
option is given, you are also told about hunks that succeeded.
|
||||
If the hunk is installed at a different line
|
||||
from the line number specified in the diff you
|
||||
are told the offset.
|
||||
@ -127,38 +124,76 @@ indicate that a hunk was installed in the
|
||||
wrong place.
|
||||
You are also told if a fuzz factor was used to make the match, in which
|
||||
case you should also be slightly suspicious.
|
||||
If the
|
||||
.B \*=verbose
|
||||
option is given, you are also told about hunks that match exactly.
|
||||
.PP
|
||||
If no original file
|
||||
.I origfile
|
||||
is specified on the command line,
|
||||
.B patch
|
||||
tries to figure out from the leading garbage what the name of the file
|
||||
to edit is.
|
||||
to edit is, using the following rules.
|
||||
.TP 3
|
||||
.B " \(bu"
|
||||
If the header is that of a context diff,
|
||||
.B patch
|
||||
takes the old and new file names in the header,
|
||||
and if there is an
|
||||
.B Index:\&
|
||||
line in the leading garbage,
|
||||
.B patch
|
||||
obtains the name in that line; any
|
||||
takes the old and new file names in the header.
|
||||
Any
|
||||
.B /dev/null
|
||||
names are ignored.
|
||||
These names are considered to be in the order (old, new, index),
|
||||
.TP
|
||||
.B " \(bu"
|
||||
If there is an
|
||||
.B Index:\&
|
||||
line in the leading garbage
|
||||
and if either the old and new names are both absent or the
|
||||
.B POSIXLY_CORRECT
|
||||
environment variable is set,
|
||||
.B patch
|
||||
takes the name in the
|
||||
.B Index:\&
|
||||
line.
|
||||
.TP
|
||||
.B " \(bu"
|
||||
For the purpose of the following rules,
|
||||
the names are considered to be in the order (old, new, index),
|
||||
regardless of the order that they appear in the header.
|
||||
.TP
|
||||
.B " \(bu"
|
||||
If some of the named files exist,
|
||||
.B patch
|
||||
uses the first name if the
|
||||
.B POSIXLY_CORRECT
|
||||
environment variable is set, and the best name otherwise.
|
||||
If no named files exist, some names are given,
|
||||
.TP
|
||||
.B " \(bu"
|
||||
If
|
||||
.B patch
|
||||
is not ignoring \s-1RCS\s0 and \s-1SCCS\s0 (see the
|
||||
.BI "\-g " num
|
||||
or
|
||||
.BI \*=get= num
|
||||
option), and no named files exist
|
||||
but an \s-1RCS\s0 or \s-1SCCS\s0 master is found,
|
||||
.B patch
|
||||
uses the first named file with an \s-1RCS\s0 or \s-1SCCS\s0 master.
|
||||
.TP
|
||||
.B " \(bu"
|
||||
If no named files exist, no \s-1RCS\s0 or \s-1SCCS\s0 master was found,
|
||||
some names are given,
|
||||
.B POSIXLY_CORRECT
|
||||
is not set, and the patch appears to create a file,
|
||||
.B patch
|
||||
uses the best name requiring the creation of the fewest directories.
|
||||
.TP
|
||||
.B " \(bu"
|
||||
If no file name results from the above heuristics, you are asked
|
||||
for the name of the file to patch.
|
||||
To determine the best of a nonempty list of file names,
|
||||
.LP
|
||||
To determine the
|
||||
.I best
|
||||
of a nonempty list of file names,
|
||||
.B patch
|
||||
first takes all the names with the fewest path name components;
|
||||
of those, it then takes all the names with the shortest basename;
|
||||
@ -175,22 +210,6 @@ If not,
|
||||
.B patch
|
||||
asks for confirmation before proceeding.
|
||||
.PP
|
||||
If an
|
||||
\s-1RCS\s0 file is handy,
|
||||
and the original file cannot be found
|
||||
or is read-only and matches the default version,
|
||||
and if version control
|
||||
(see the
|
||||
.B \-V
|
||||
or
|
||||
.B \*=version\-control
|
||||
option)
|
||||
is set to
|
||||
.BR existing ,
|
||||
.B patch
|
||||
attempts to get and lock the file.
|
||||
\s-1SCCS\s0 is treated in a similar way.
|
||||
.PP
|
||||
The upshot of all this is that you should be able to say, while in a news
|
||||
interface, something like the following:
|
||||
.Sp
|
||||
@ -213,20 +232,38 @@ mentioned previously.
|
||||
.TP 3
|
||||
\fB\-b\fP or \fB\*=backup\fP
|
||||
Make backup files.
|
||||
That is, when patching a file,
|
||||
rename or copy the original instead of removing it.
|
||||
When backing up a file that does not exist,
|
||||
an empty, unreadable backup file is created
|
||||
as a placeholder to represent the nonexistent file.
|
||||
.Sp
|
||||
This option is equivalent to
|
||||
.BR \*=version\-control=simple ;
|
||||
see the
|
||||
.B \-V
|
||||
or
|
||||
.B \*=version\-control
|
||||
option for details.
|
||||
In older versions of
|
||||
.BR patch ,
|
||||
this option had an argument specifying the simple backup suffix;
|
||||
this argument has been moved to the
|
||||
.B \-z
|
||||
option.
|
||||
.TP
|
||||
.B \*=backup\-if\-mismatch
|
||||
Back up a file if the patch does not match the file exactly
|
||||
and if backups are not otherwise requested.
|
||||
The backup file name is calculated as usual,
|
||||
except that if the version control method is
|
||||
.BR none ,
|
||||
a simple backup name is used.
|
||||
This is the default unless the
|
||||
.B POSIXLY_CORRECT
|
||||
environment variable is set.
|
||||
.TP
|
||||
.B \*=no\-backup\-if\-mismatch
|
||||
Do not back up a file if the patch does not match the file exactly
|
||||
and if backups are not otherwise requested.
|
||||
This is the default if the
|
||||
.B POSIXLY_CORRECT
|
||||
environment variable is set.
|
||||
.TP
|
||||
\fB\-B\fP \fIpref\fP or \fB\*=prefix=\fP\fIpref\fP
|
||||
Prefix simple backup file names with
|
||||
.IR pref .
|
||||
@ -249,20 +286,17 @@ the patch should be generated by
|
||||
\fB\-c\fP or \fB\*=context\fP
|
||||
Interpret the patch file as a ordinary context diff.
|
||||
.TP
|
||||
\fB\*=verbose\fP
|
||||
Output extra information about the work being done.
|
||||
.TP
|
||||
\fB\-d\fP \fIdir\fP or \fB\*=directory=\fP\fIdir\fP
|
||||
Change to the directory
|
||||
.I dir
|
||||
immediately, before doing
|
||||
anything else.
|
||||
.TP
|
||||
\fB\-D\fP \fIsym\fP or \fB\*=ifdef=\fP\fIsym\fP
|
||||
\fB\-D\fP \fIdefine\fP or \fB\*=ifdef=\fP\fIdefine\fP
|
||||
Use the
|
||||
.BR #ifdef " .\|.\|. " #endif
|
||||
construct to mark changes, with
|
||||
.I sym
|
||||
.I define
|
||||
as the differentiating symbol.
|
||||
.TP
|
||||
.B "\*=dry\-run"
|
||||
@ -277,7 +311,7 @@ script.
|
||||
Remove output files that are empty after the patches have been applied.
|
||||
Normally this option is unnecessary, since
|
||||
.B patch
|
||||
can examine the timestamps on the header to determine whether a file
|
||||
can examine the time stamps on the header to determine whether a file
|
||||
should exist after patching.
|
||||
However, if the input is not a context diff or if the
|
||||
.B POSIXLY_CORRECT
|
||||
@ -300,7 +334,7 @@ This option does not suppress commentary; use
|
||||
.B \-s
|
||||
for that.
|
||||
.TP
|
||||
\fB\-F\fP \fInumber\fP or \fB\*=fuzz=\fP\fInumber\fP
|
||||
\fB\-F\fP \fInum\fP or \fB\*=fuzz=\fP\fInum\fP
|
||||
Set the maximum fuzz factor.
|
||||
This option only applies to diffs that have context, and causes
|
||||
.B patch
|
||||
@ -309,19 +343,25 @@ Note that a larger fuzz factor increases the odds of a faulty patch.
|
||||
The default fuzz factor is 2, and it may not be set to more than
|
||||
the number of lines of context in the context diff, ordinarily 3.
|
||||
.TP
|
||||
\fB\-g\fP or \fB\*=get\fP
|
||||
If a file does not exist or is read-only and matches the default version,
|
||||
get it from \s-1RCS\s0 if it is under \s-2RCS\s0 control;
|
||||
similarly for \s-1SCCS\s0.
|
||||
If the
|
||||
\fB\-g\fP \fInum\fP or \fB\*=get=\fP\fInum\fP
|
||||
This option controls
|
||||
.BR patch 's
|
||||
actions when a file is under \s-1RCS\s0 or \s-1SCCS\s0 control,
|
||||
and does not exist or is read-only and matches the default version.
|
||||
If
|
||||
.I num
|
||||
is positive,
|
||||
.B patch
|
||||
gets (or checks out) the file from the revision control system; if zero,
|
||||
.B patch
|
||||
ignores \s-1RCS\s0 and \s-1SCCS\s0 and does not get the file; and if negative,
|
||||
.B patch
|
||||
asks the user whether to get the file.
|
||||
The default value of this option is given by the value of the
|
||||
.B PATCH_GET
|
||||
environment variable is set, this is the default.
|
||||
.TP
|
||||
\fB\-G\fP or \fB\*=no\-get\fP
|
||||
Do not get files from \s-1RCS\s0 or \s-2SCCS\s0.
|
||||
This is the default unless the
|
||||
.B PATCH_GET
|
||||
environment variable is set.
|
||||
environment variable if it is set; if not, the default value is zero if
|
||||
.B POSIXLY_CORRECT
|
||||
is set, negative otherwise.
|
||||
.TP
|
||||
.B "\*=help"
|
||||
Print a summary of options and exit.
|
||||
@ -351,14 +391,14 @@ Ignore patches that seem to be reversed or already applied.
|
||||
See also
|
||||
.BR \-R .
|
||||
.TP
|
||||
\fB\-o\fP \fIfile\fP or \fB\*=output=\fP\fIfile\fP
|
||||
\fB\-o\fP \fIoutfile\fP or \fB\*=output=\fP\fIoutfile\fP
|
||||
Send output to
|
||||
.I file
|
||||
.I outfile
|
||||
instead of patching files in place.
|
||||
.TP
|
||||
\fB\-p\fP\fInumber\fP or \fB\*=strip\fP\fB=\fP\fInumber\fP
|
||||
\fB\-p\fP\fInum\fP or \fB\*=strip\fP\fB=\fP\fInum\fP
|
||||
Strip the smallest prefix containing
|
||||
.I number
|
||||
.I num
|
||||
leading slashes from each file name found in the patch file.
|
||||
A sequence of one or more adjacent slashes is counted as a single slash.
|
||||
This controls how file names found in the patch file are treated, in case
|
||||
@ -389,19 +429,10 @@ Whatever you end up with is looked for either in the current directory,
|
||||
or the directory specified by the
|
||||
.B \-d
|
||||
option.
|
||||
With \s-1GNU\s0
|
||||
.BR patch ,
|
||||
the two-argument
|
||||
.BI "\-p " N
|
||||
form of this option is equivalent to one-argument
|
||||
.BI \-p N
|
||||
form, but this is not true of traditional
|
||||
.BR patch ,
|
||||
so the one-argument form is recommended for portability.
|
||||
.TP
|
||||
\fB\-r\fP \fIfile\fP or \fB\*=reject\-file=\fP\fIfile\fP
|
||||
\fB\-r\fP \fIrejectfile\fP or \fB\*=reject\-file=\fP\fIrejectfile\fP
|
||||
Put rejects into
|
||||
.I file
|
||||
.I rejectfile
|
||||
instead of the default
|
||||
.B \&.rej
|
||||
file.
|
||||
@ -449,6 +480,19 @@ line
|
||||
in the patch; and assume that patches are reversed if they look like
|
||||
they are.
|
||||
.TP
|
||||
\fB\-T\fP or \fB\*=set\-time\fP
|
||||
Set the modification and access times of patched files from time stamps
|
||||
given in context diff headers, assuming that the context diff headers
|
||||
use local time. This option is not recommended, because patches using
|
||||
local time cannot easily be used by people in other time zones, and
|
||||
because local time stamps are ambiguous when local clocks move backwards
|
||||
during daylight-saving time adjustments. Instead of using this option,
|
||||
generate patches with \s-1UTC\s0 and use the
|
||||
.B \-Z
|
||||
or
|
||||
.B \*=set\-utc
|
||||
option instead.
|
||||
.TP
|
||||
\fB\-u\fP or \fB\*=unified\fP
|
||||
Interpret the patch file as a unified context diff.
|
||||
.TP
|
||||
@ -460,8 +504,8 @@ revision header and patch level, and exit.
|
||||
\fB\-V\fP \fImethod\fP or \fB\*=version\-control=\fP\fImethod\fP
|
||||
Use
|
||||
.I method
|
||||
when creating
|
||||
backup file names. The type of backups made can also be given in the
|
||||
to determine
|
||||
backup file names. The method can also be given by the
|
||||
.B PATCH_VERSION_CONTROL
|
||||
(or, if that's not set, the
|
||||
.BR VERSION_CONTROL )
|
||||
@ -484,7 +528,8 @@ Make numbered backups of files that already have them,
|
||||
otherwise simple backups.
|
||||
.TP
|
||||
\fBnone\fP
|
||||
Do not make backups.
|
||||
Do not make backups, unless backup-if-mismatch is in effect
|
||||
and patches do not match files.
|
||||
This is the default.
|
||||
.TP
|
||||
\fBnumbered\fP or \fBt\fP
|
||||
@ -497,9 +542,7 @@ where
|
||||
is the version number.
|
||||
.TP
|
||||
\fBsimple\fP or \fBnever\fP
|
||||
Make simple backups. That is, when patching a file
|
||||
.IR F ,
|
||||
rename or copy the original instead of removing it.
|
||||
Make simple backups.
|
||||
The
|
||||
.B \-B
|
||||
or
|
||||
@ -529,7 +572,10 @@ would make the name too long, then
|
||||
replaces the last character of the file name.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-x\fP \fInumber\fP or \fB\*=debug=\fP\fInumber\fP
|
||||
\fB\*=verbose\fP
|
||||
Output extra information about the work being done.
|
||||
.TP
|
||||
\fB\-x\fP \fInum\fP or \fB\*=debug=\fP\fInum\fP
|
||||
Set internal debugging flags of interest only to
|
||||
.B patch
|
||||
patchers.
|
||||
@ -544,23 +590,72 @@ the backup file name for
|
||||
is
|
||||
.BR src/patch/.del/util.c .
|
||||
.TP
|
||||
\fB\-z\fP \fIsuff\fP or \fB\*=suffix=\fP\fIsuff\fP
|
||||
\fB\-z\fP \fIsuffix\fP or \fB\*=suffix=\fP\fIsuffix\fP
|
||||
Use
|
||||
.I suff
|
||||
.I suffix
|
||||
as the simple backup suffix.
|
||||
The backup extension may also be specified by the
|
||||
.B SIMPLE_BACKUP_SUFFIX
|
||||
environment variable, which is overridden by this option.
|
||||
.TP
|
||||
\fB\-Z\fP or \fB\*=set\-utc\fP
|
||||
Set the modification and access times of patched files from time stamps
|
||||
given in context diff headers, assuming that the context diff headers
|
||||
use Coordinated Universal Time (\s-1UTC\s0, often known as \s-1GMT\s0).
|
||||
Also see the
|
||||
.B \-T
|
||||
or
|
||||
.B \*=set\-time
|
||||
option.
|
||||
.Sp
|
||||
The
|
||||
.B \-Z
|
||||
or
|
||||
.B \*=set\-utc
|
||||
and
|
||||
.B \-T
|
||||
or
|
||||
.B \*=set\-time
|
||||
options normally refrain from setting a file's time if the file's original time
|
||||
does not match the time given in the patch header, or if its
|
||||
contents do not match the patch exactly. However, if the
|
||||
.B \-f
|
||||
or
|
||||
.B \*=force
|
||||
option is given, the file time is set regardless.
|
||||
.Sp
|
||||
Due to the limitations of
|
||||
.B diff
|
||||
output format, these options cannot update the times of files whose
|
||||
contents have not changed. Also, if you use these options, you should remove
|
||||
(e.g. with
|
||||
.BR "make\ clean" )
|
||||
all files that depend on the patched files, so that later invocations of
|
||||
.B make
|
||||
do not get confused by the patched files' times.
|
||||
.SH ENVIRONMENT
|
||||
.TP 3
|
||||
\fBPATCH_GET\fP
|
||||
This specifies whether
|
||||
.B patch
|
||||
gets missing or read-only files from \s-1RCS\s0 or \s-1SCCS\s0
|
||||
by default; see the
|
||||
.B \-g
|
||||
or
|
||||
.B \*=get
|
||||
option.
|
||||
.TP
|
||||
.B POSIXLY_CORRECT
|
||||
If set,
|
||||
.B patch
|
||||
conforms more strictly to the \s-1POSIX\s0 standard:
|
||||
it takes the first existing file when intuiting file names from diff headers,
|
||||
it takes the first existing file from the list (old, new, index)
|
||||
when intuiting file names from diff headers,
|
||||
it does not remove files that are empty after patching,
|
||||
and it requires that all options precede the
|
||||
files in the command line.
|
||||
it does not ask whether to get files from \s-1RCS\s0 or \s-1SCCS\s0,
|
||||
it requires that all options precede the
|
||||
files in the command line,
|
||||
and by default it does not make backup files.
|
||||
.TP
|
||||
.B SIMPLE_BACKUP_SUFFIX
|
||||
Extension to use for simple backup file names instead of
|
||||
@ -575,33 +670,19 @@ it is normally
|
||||
.B /tmp
|
||||
on Unix hosts.
|
||||
.TP
|
||||
\fBPATCH_VERSION_CONTROL\fP or \fBVERSION_CONTROL\fP
|
||||
\fBVERSION_CONTROL\fP or \fBPATCH_VERSION_CONTROL\fP
|
||||
Selects version control style; see the
|
||||
.B \-v
|
||||
or
|
||||
.B \*=version\-control
|
||||
option.
|
||||
.TP
|
||||
\fBPATCH_GET\fP
|
||||
If set,
|
||||
.B patch
|
||||
gets missing or read-only files from \s-1RCS\s0 or \s-1SCCS\s0
|
||||
by default; see the
|
||||
.B \-g
|
||||
or
|
||||
.B \*= get
|
||||
and the
|
||||
.B \-G
|
||||
or
|
||||
.B \*= no\-get
|
||||
options.
|
||||
.SH FILES
|
||||
.TP 3
|
||||
.IB $TMPDIR "/p\(**"
|
||||
temporary files
|
||||
.TP
|
||||
.B /dev/tty
|
||||
console; used to get answers to questions asked of the user
|
||||
controlling terminal; used to get answers to questions asked of the user
|
||||
.SH "SEE ALSO"
|
||||
.BR diff (1),
|
||||
.BR ed (1)
|
||||
@ -622,9 +703,18 @@ The names
|
||||
and
|
||||
.I new
|
||||
should not contain any slashes.
|
||||
Here is an example:
|
||||
The
|
||||
.B diff
|
||||
command's headers should have dates
|
||||
and times in Universal Time using traditional Unix format,
|
||||
so that patch recipients can use the
|
||||
.B \-Z
|
||||
or
|
||||
.B \*=set\-utc
|
||||
option.
|
||||
Here is an example command, using Bourne shell syntax:
|
||||
.Sp
|
||||
\fBdiff \-Naur version\-2.2 version\-2.3\fP
|
||||
\fBLC_ALL=C TZ=UTC0 diff \-Naur gcc\-2.7 gcc\-2.8\fP
|
||||
.PP
|
||||
Tell your recipients how to apply the patch
|
||||
by telling them which directory to
|
||||
@ -646,19 +736,14 @@ If you put a
|
||||
line in with the patch, it won't let them apply
|
||||
patches out of order without some warning.
|
||||
.PP
|
||||
Make sure you've specified the file names right, either in a
|
||||
context diff header, or with an
|
||||
.B Index:\&
|
||||
line.
|
||||
.PP
|
||||
You can create a file by sending out a diff that compares an
|
||||
empty file (such as
|
||||
.BR /dev/null )
|
||||
You can create a file by sending out a diff that compares
|
||||
.B /dev/null
|
||||
or an empty file dated the Epoch (1970-01-01 00:00:00 \s-1UTC\s0)
|
||||
to the file you want to create.
|
||||
This only works if the file you want to create doesn't exist already in
|
||||
the target directory.
|
||||
Conversely, you can remove a file by sending out a diff that compares the
|
||||
file to be deleted with an empty file.
|
||||
Conversely, you can remove a file by sending out a context diff that compares
|
||||
the file to be deleted with an empty file dated the Epoch.
|
||||
The file will be removed unless the
|
||||
.B POSIXLY_CORRECT
|
||||
environment variable is set and the
|
||||
@ -669,6 +754,8 @@ option is not given.
|
||||
An easy way to generate patches that create and remove files
|
||||
is to use \s-1GNU\s0
|
||||
.BR diff 's
|
||||
.B \-N
|
||||
or
|
||||
.B \*=new\-file
|
||||
option.
|
||||
.PP
|
||||
@ -723,49 +810,14 @@ where there is a line
|
||||
in your makefile), since the recipient should be
|
||||
able to regenerate the derived files anyway.
|
||||
If you must send diffs of derived files,
|
||||
ensure that the diffs for each derived file
|
||||
follow the diffs for the files that it depends on,
|
||||
so that the dependencies will be preserved as
|
||||
.B patch
|
||||
updates the files one by one.
|
||||
Here is a sample shell script that output patches in an order that
|
||||
should preserve dependencies:
|
||||
.nf
|
||||
.Sp
|
||||
.ft B
|
||||
.in +3n
|
||||
#! /bin/sh
|
||||
.Sp
|
||||
.ne 2
|
||||
old=${1?}
|
||||
new=${2?}
|
||||
.Sp
|
||||
.ne 10
|
||||
fs=
|
||||
for f in `
|
||||
diff \-Nqr $old $new |
|
||||
sed \-e "s,.\(** $new/,," \-e 's, differ$,,'`
|
||||
do
|
||||
if [ \-f $new/$f ]
|
||||
then fs="$fs $f"
|
||||
else diff \-au $old/$f /dev/null
|
||||
fi
|
||||
done
|
||||
.Sp
|
||||
.ne 10
|
||||
case $fs in
|
||||
?\(**)
|
||||
for f in `cd $new; ls \-rt $fs`
|
||||
do
|
||||
if [ \-f $old/$f ]
|
||||
then diff \-au $old/$f $new/$f
|
||||
else diff \-au /dev/null $new/$f
|
||||
fi
|
||||
done
|
||||
esac
|
||||
.in
|
||||
.ft
|
||||
.fi
|
||||
generate the diffs using \s-1UTC\s0,
|
||||
have the recipients apply the patch with the
|
||||
.B \-Z
|
||||
or
|
||||
.B \*=set\-utc
|
||||
option, and have them remove any unpatched files that depend on patched files
|
||||
(e.g. with
|
||||
.BR "make\ clean" ).
|
||||
.PP
|
||||
While you may be able to get away with putting 582 diff listings into
|
||||
one file, it may be wiser to group related patches into separate files in
|
||||
@ -817,6 +869,150 @@ guessing.
|
||||
However, the results are guaranteed to be correct only when the patch is
|
||||
applied to exactly the same version of the file that the patch was
|
||||
generated from.
|
||||
.SH "COMPATIBILITY ISSUES"
|
||||
The \s-1POSIX\s0 standard specifies behavior that differs from
|
||||
.BR patch 's
|
||||
traditional behavior.
|
||||
You should be aware of these differences if you must interoperate with
|
||||
.B patch
|
||||
versions 2.1 and earlier, which are not \s-1POSIX\s0-compliant.
|
||||
.TP 3
|
||||
.B " \(bu"
|
||||
In traditional
|
||||
.BR patch ,
|
||||
the
|
||||
.B \-p
|
||||
option's operand was optional, and a bare
|
||||
.B \-p
|
||||
was equivalent to
|
||||
.BR \-p0.
|
||||
The
|
||||
.B \-p
|
||||
option now requires an operand, and
|
||||
.B "\-p\ 0"
|
||||
is now equivalent to
|
||||
.BR \-p0 .
|
||||
For maximum compatibility, use options like
|
||||
.B \-p0
|
||||
and
|
||||
.BR \-p1 .
|
||||
.Sp
|
||||
Also,
|
||||
traditional
|
||||
.B patch
|
||||
simply counted slashes when stripping path prefixes;
|
||||
.B patch
|
||||
now counts pathname components.
|
||||
That is, a sequence of one or more adjacent slashes
|
||||
now counts as a single slash.
|
||||
For maximum portability, avoid sending patches containing
|
||||
.B //
|
||||
in file names.
|
||||
.TP
|
||||
.B " \(bu"
|
||||
In traditional
|
||||
.BR patch ,
|
||||
simple backups were enabled by default.
|
||||
This behavior is now enabled with the
|
||||
.B \-b
|
||||
or
|
||||
.B \*=backup
|
||||
option, or by setting the
|
||||
.B VERSION_CONTROL
|
||||
environment variable to
|
||||
.BR simple .
|
||||
.Sp
|
||||
Conversely, in \s-1POSIX\s0
|
||||
.BR patch ,
|
||||
backups are never made, even when there is a mismatch.
|
||||
In \s-1GNU\s0
|
||||
.BR patch ,
|
||||
this behavior is enabled with the
|
||||
.B \*=no\-backup\-if\-mismatch
|
||||
option or by setting the
|
||||
.B POSIXLY_CORRECT
|
||||
environment variable.
|
||||
.Sp
|
||||
The
|
||||
.BI \-b " suffix"
|
||||
option
|
||||
of traditional
|
||||
.B patch
|
||||
is equivalent to the
|
||||
.BI "\-b \-z" " suffix"
|
||||
options of \s-1GNU\s0
|
||||
.BR patch .
|
||||
.TP
|
||||
.B " \(bu"
|
||||
Traditional
|
||||
.B patch
|
||||
used a complicated (and incompletely documented) method
|
||||
to intuit the name of the file to be patched from the patch header.
|
||||
This method was not \s-1POSIX\s0-compliant, and had a few gotchas.
|
||||
Now
|
||||
.B patch
|
||||
uses a different, equally complicated (but better documented) method
|
||||
that is optionally \s-1POSIX\s0-compliant; we hope it has
|
||||
fewer gotchas. The two methods are compatible if the
|
||||
file names in the context diff header and the
|
||||
.B Index:\&
|
||||
line are all identical after prefix-stripping.
|
||||
Your patch is normally compatible if each header's file names
|
||||
all contain the same number of slashes.
|
||||
.TP
|
||||
.B " \(bu"
|
||||
When traditional
|
||||
.B patch
|
||||
asked the user a question, it sent the question to standard error
|
||||
and looked for an answer from
|
||||
the first file in the following list that was a terminal:
|
||||
standard error, standard output,
|
||||
.BR /dev/tty ,
|
||||
and standard input.
|
||||
Now
|
||||
.B patch
|
||||
sends questions to standard output and gets answers from
|
||||
.BR /dev/tty .
|
||||
Defaults for some answers have been changed so that
|
||||
.B patch
|
||||
never goes into an infinite loop when using default answers.
|
||||
.TP
|
||||
.B " \(bu"
|
||||
Traditional
|
||||
.B patch
|
||||
exited with a status value that counted the number of bad hunks,
|
||||
or with status 1 if there was real trouble.
|
||||
Now
|
||||
.B patch
|
||||
exits with status 1 if some hunks failed,
|
||||
or with 2 if there was real trouble.
|
||||
.TP
|
||||
.B " \(bu"
|
||||
Limit yourself to the following options when sending instructions
|
||||
meant to be executed by anyone running \s-1GNU\s0
|
||||
.BR patch ,
|
||||
traditional
|
||||
.BR patch ,
|
||||
or a \s-1POSIX\s0-compliant
|
||||
.BR patch .
|
||||
Spaces are significant in the following list, and operands are required.
|
||||
.Sp
|
||||
.nf
|
||||
.in +3
|
||||
.ne 11
|
||||
.B \-c
|
||||
.BI \-d " dir"
|
||||
.BI \-D " define"
|
||||
.B \-e
|
||||
.B \-l
|
||||
.B \-n
|
||||
.B \-N
|
||||
.BI \-o " outfile"
|
||||
.BI \-p num
|
||||
.B \-R
|
||||
.BI \-r " rejectfile"
|
||||
.in
|
||||
.fi
|
||||
.SH BUGS
|
||||
.B patch
|
||||
could be smarter about partial matches, excessively deviant offsets and
|
||||
@ -860,7 +1056,8 @@ Larry Wall wrote the original version of
|
||||
.BR patch .
|
||||
Paul Eggert removed
|
||||
.BR patch 's
|
||||
arbitrary limits, added support for binary files,
|
||||
arbitrary limits; added support for binary files,
|
||||
setting file times, and deleting files;
|
||||
and made it conform better to \s-1POSIX\s0.
|
||||
Other contributors include Wayne Davison, who added unidiff support,
|
||||
and David MacKenzie, who added configuration and backup support.
|
||||
|
||||
@ -1,139 +0,0 @@
|
||||
/* config.h for compiling `patch' with DJGPP for MS-DOS and MS-Windows.
|
||||
Please keep this file as similar as possible to ../../config.h
|
||||
to simplify maintenance later. */
|
||||
|
||||
/* This does most of the work; the rest of this file defines only those
|
||||
symbols that <sys/config.h> doesn't define correctly. */
|
||||
#include <sys/config.h>
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
/* #undef _ALL_SOURCE */
|
||||
#endif
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
/* #undef CLOSEDIR_VOID */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
|
||||
/* Define if you support file names longer than 14 characters. */
|
||||
#define HAVE_LONG_FILE_NAMES 1
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
/* Define if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
/* #undef mode_t */
|
||||
|
||||
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||
/* #undef off_t */
|
||||
|
||||
/* Define if the system does not provide POSIX.1 features except
|
||||
with this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
/* #undef RETSIGTYPE */
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
/* #undef STDC_HEADERS */
|
||||
|
||||
/* Define if there is a member named d_ino in the struct describing
|
||||
directory headers. */
|
||||
/* #undef D_INO_IN_DIRENT */
|
||||
|
||||
/* Define if memchr works. */
|
||||
/* #undef HAVE_MEMCHR */
|
||||
|
||||
/* Define if you have the _doprintf function. */
|
||||
/* #undef HAVE__DOPRINTF */
|
||||
|
||||
/* Define if you have the isascii function. */
|
||||
/* #undef HAVE_ISASCII */
|
||||
|
||||
/* Define if you have the memchr function. */
|
||||
/* #undef HAVE_MEMCHR 1 */
|
||||
|
||||
/* Define if you have the memcmp function. */
|
||||
#define HAVE_MEMCMP 1
|
||||
|
||||
/* Define if you have the mkdir function. */
|
||||
/* #undef HAVE_MKDIR */
|
||||
|
||||
/* Define if you have the mktemp function. */
|
||||
#define HAVE_MKTEMP 1
|
||||
|
||||
/* Define if you have the pathconf function. */
|
||||
#define HAVE_PATHCONF 1
|
||||
|
||||
/* Define if you have the rename function. */
|
||||
/* #undef HAVE_RENAME */
|
||||
|
||||
/* Define if you have the sigaction function. */
|
||||
/* #undef HAVE_SIGACTION */
|
||||
|
||||
/* Define if you have the sigprocmask function. */
|
||||
#define HAVE_SIGPROCMASK 1
|
||||
|
||||
/* Define if you have the sigsetmask function. */
|
||||
/* #undef HAVE_SIGSETMASK */
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
/* #undef HAVE_DIRENT_H */
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
/* #undef HAVE_FCNTL_H */
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
/* #undef HAVE_LIMITS_H */
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
/* #undef HAVE_STRING_H */
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
|
||||
/* Define if you have the <varargs.h> header file. */
|
||||
/* #undef HAVE_VARARGS_H */
|
||||
|
||||
|
||||
/* PC-specific definitions */
|
||||
|
||||
#define chdir chdir_safer
|
||||
int chdir_safer (char const *);
|
||||
|
||||
#define FILESYSTEM_PREFIX_LEN(f) ((f)[0] && (f)[1] == ':' ? 2 : 0)
|
||||
#define ISSLASH(c) ((c) == '/' || (c) == '\\')
|
||||
|
||||
#define HAVE_DOS_FILE_NAMES 1
|
||||
|
||||
#define HAVE_SETMODE 1
|
||||
#ifdef WIN32
|
||||
# define setmode _setmode
|
||||
#endif
|
||||
|
||||
#define TMPDIR "c:"
|
||||
@ -1,35 +1,38 @@
|
||||
# Edit Makefile.in to produce Makefile for DJGPP v2
|
||||
# $Id: config.sed,v 1.4 1997/05/26 17:52:29 eggert Exp $
|
||||
1c\
|
||||
/* config.h for compiling `patch' with DJGPP for MS-DOS and MS-Windows.\
|
||||
Please keep this file as similar as possible to ../../config.h\
|
||||
to simplify maintenance later. */\
|
||||
\
|
||||
/* This does most of the work; the rest of this file defines only those\
|
||||
symbols that <sys/config.h> doesn't define correctly. */\
|
||||
#include <sys/config.h>
|
||||
|
||||
1i\
|
||||
# Makefile generated by "configure.bat" for DJGPP v2\
|
||||
s/#undef HAVE_LONG_FILE_NAMES/#define HAVE_LONG_FILE_NAMES 1/
|
||||
s/#undef HAVE_MEMCMP/#define HAVE_MEMCMP 1/
|
||||
s/#undef HAVE_MKTEMP/#define HAVE_MKTEMP 1/
|
||||
s/#undef HAVE_PATHCONF/#define HAVE_PATHCONF 1/
|
||||
s/#undef HAVE_RAISE/#define HAVE_RAISE 1/
|
||||
s/#undef HAVE_SIGPROCMASK/#define HAVE_SIGPROCMASK 1/
|
||||
s/#undef HAVE_UTIME_H/#define HAVE_UTIME_H 1/
|
||||
s/#undef HAVE_STRUCT_UTIMBUF/#define HAVE_STRUCT_UTIMBUF 1/
|
||||
s/#undef HAVE_VPRINTF/#define HAVE_VPRINTF 1/
|
||||
|
||||
/@SET_MAKE@/d
|
||||
|
||||
s|@CC@|gcc|g
|
||||
s|@ed_PROGRAM@|ed|g
|
||||
s|@INSTALL@|${DJDIR}/bin/ginstall -c|g
|
||||
s|@INSTALL_PROGRAM@|${INSTALL}|g
|
||||
s|@INSTALL_DATA@|${INSTALL} -m 644|g
|
||||
|
||||
s|@CFLAGS@|-g -O2|g
|
||||
s|@CPPFLAGS@|-I$(srcdir)/pc/djgpp|g
|
||||
s|@DEFS@|-DHAVE_CONFIG_H|g
|
||||
s|@LDFLAGS@||g
|
||||
s|@LIBOBJS@|getopt1.o getopt.o chdirsaf.o|g
|
||||
s|@LIBS@||g
|
||||
s|@PACKAGE@|patch|g
|
||||
/@VERSION@/d
|
||||
|
||||
s|@prefix@|${DJDIR}|g
|
||||
s|@exec_prefix@|${prefix}|g
|
||||
|
||||
/^CONFIG_HDRS *=/s|=.*|= pc/djgpp/config.h|
|
||||
/^CONFIG_STATUS *=/s|=.*|= $(srcdir)/pc/djgpp/configure.bat|
|
||||
/^ \$(SHELL) \$(CONFIG_STATUS) *$/s// $(CONFIG_STATUS) $(srcdir)/
|
||||
s,#undef.*,/* & */,
|
||||
|
||||
$a\
|
||||
chdirsaf.o: chdirsaf.c\
|
||||
# Use sed instead of cp, since cp might not be installed.\
|
||||
chdirsaf.c: pc/chdirsaf.c; sed -e '' $? > $@\
|
||||
distclean::; rm -f chdirsaf.c
|
||||
/* DGJPP-specific definitions */\
|
||||
\
|
||||
#define chdir chdir_safer\
|
||||
int chdir_safer (char const *);\
|
||||
\
|
||||
#define FILESYSTEM_PREFIX_LEN(f) ((f)[0] && (f)[1] == ':' ? 2 : 0)\
|
||||
#define ISSLASH(c) ((c) == '/' || (c) == '\\\\')\
|
||||
\
|
||||
#define HAVE_DOS_FILE_NAMES 1\
|
||||
\
|
||||
#define HAVE_SETMODE 1\
|
||||
#ifdef WIN32\
|
||||
# define setmode _setmode\
|
||||
#endif\
|
||||
\
|
||||
#define TMPDIR "c:"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
@echo off
|
||||
Rem Configure patch for DJGPP v2.
|
||||
Rem $Id: configure.bat,v 1.3 1997/05/26 17:52:29 eggert Exp $
|
||||
Rem $Id: configure.bat,v 1.4 1997/06/17 06:52:12 eggert Exp $
|
||||
|
||||
Rem The DOS shell has fixed-size environment storage.
|
||||
Rem When the environment is full, the shell prints
|
||||
@ -15,7 +15,7 @@ if not "%1" == "" set srcdir=%1
|
||||
if not "%1" == "" if not "%srcdir%" == "%1" goto SmallEnv
|
||||
|
||||
Rem Create Makefile
|
||||
sed -f %srcdir%/pc/djgpp/config.sed -e "s,@srcdir@,%srcdir%,g" %srcdir%/Makefile.in >Makefile
|
||||
sed -f %srcdir%/pc/djgpp/configure.sed -e "s,@srcdir@,%srcdir%,g" %srcdir%/Makefile.in >Makefile
|
||||
sed -n -e "/^VERSION/p" %srcdir%/configure.in >>Makefile
|
||||
|
||||
goto Exit
|
||||
|
||||
36
pc/djgpp/configure.sed
Normal file
36
pc/djgpp/configure.sed
Normal file
@ -0,0 +1,36 @@
|
||||
# Edit Makefile.in to produce Makefile for DJGPP v2
|
||||
# $Id: configure.sed,v 1.8 1997/06/18 06:26:43 eggert Exp $
|
||||
|
||||
1i\
|
||||
# Makefile generated by "configure.bat" for DJGPP v2\
|
||||
|
||||
/@SET_MAKE@/d
|
||||
|
||||
s|@CC@|gcc|g
|
||||
s|@ed_PROGRAM@|ed|g
|
||||
s|@INSTALL@|${DJDIR}/bin/ginstall -c|g
|
||||
s|@INSTALL_PROGRAM@|${INSTALL}|g
|
||||
s|@INSTALL_DATA@|${INSTALL} -m 644|g
|
||||
s|@program_transform_name@||g
|
||||
|
||||
s|@CFLAGS@|-g -O2|g
|
||||
s|@CPPFLAGS@|-I$(srcdir)/pc/djgpp|g
|
||||
s|@DEFS@|-DHAVE_CONFIG_H|g
|
||||
s|@LDFLAGS@||g
|
||||
s|@LIBOBJS@|getopt1.o getopt.o chdirsaf.o|g
|
||||
s|@LIBS@||g
|
||||
s|@PACKAGE@|patch|g
|
||||
/@VERSION@/d
|
||||
|
||||
s|@prefix@|${DJDIR}|g
|
||||
s|@exec_prefix@|${prefix}|g
|
||||
|
||||
/^CONFIG_STATUS *=/s|=.*|= $(srcdir)/pc/djgpp/configure.bat|
|
||||
/^ \$(SHELL) \$(CONFIG_STATUS) *$/s// $(CONFIG_STATUS) $(srcdir)/
|
||||
|
||||
$a\
|
||||
config.h: config.hin pc/djgpp/config.sed; sed -f $(srcdir)/pc/djgpp/config.sed $(srcdir)/config.hin >$@\
|
||||
chdirsaf.o: chdirsaf.c\
|
||||
# Use sed instead of cp, since cp might not be installed.\
|
||||
chdirsaf.c: pc/chdirsaf.c; sed -e '' $? > $@\
|
||||
distclean::; rm -f chdirsaf.c
|
||||
195
pch.c
195
pch.c
@ -1,6 +1,6 @@
|
||||
/* reading patches */
|
||||
|
||||
/* $Id: pch.c,v 1.16 1997/05/26 17:52:29 eggert Exp $ */
|
||||
/* $Id: pch.c,v 1.23 1997/06/17 06:52:12 eggert Exp $ */
|
||||
|
||||
/*
|
||||
Copyright 1986, 1987, 1988 Larry Wall
|
||||
@ -36,7 +36,9 @@ If not, write to the Free Software Foundation,
|
||||
/* Patch (diff listing) abstract type. */
|
||||
|
||||
static FILE *pfp; /* patch file pointer */
|
||||
static int p_says_nonexistent[2]; /* [0] for old file, [1] for new */
|
||||
static int p_says_nonexistent[2]; /* [0] for old file, [1] for new;
|
||||
value is 0 for nonempty, 1 for empty, 2 for nonexistent */
|
||||
static time_t p_timestamp[2]; /* timestamps in patch headers */
|
||||
static off_t p_filesize; /* size of the patch file */
|
||||
static LINENUM p_first; /* 1st line number */
|
||||
static LINENUM p_newfirst; /* 1st line number of replacement */
|
||||
@ -97,6 +99,7 @@ open_patch_file(filename)
|
||||
struct stat st;
|
||||
if (!filename || !*filename || strEQ (filename, "-"))
|
||||
{
|
||||
file_offset stdin_pos;
|
||||
#if HAVE_SETMODE
|
||||
if (binary_transput)
|
||||
{
|
||||
@ -107,10 +110,10 @@ open_patch_file(filename)
|
||||
#endif
|
||||
if (fstat (STDIN_FILENO, &st) != 0)
|
||||
pfatal ("fstat");
|
||||
if (S_ISREG (st.st_mode))
|
||||
if (S_ISREG (st.st_mode) && (stdin_pos = file_tell (stdin)) != -1)
|
||||
{
|
||||
pfp = stdin;
|
||||
file_pos = file_tell (stdin);
|
||||
file_pos = stdin_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -118,7 +121,9 @@ open_patch_file(filename)
|
||||
pfp = fopen (TMPPATNAME, "w+b");
|
||||
if (!pfp)
|
||||
pfatal ("can't create `%s'", TMPPATNAME);
|
||||
while ((charsread = fread (buf, 1, bufsize, stdin)) != 0)
|
||||
for (st.st_size = 0;
|
||||
(charsread = fread (buf, 1, bufsize, stdin)) != 0;
|
||||
st.st_size += charsread)
|
||||
if (fwrite (buf, 1, charsread, pfp) != charsread)
|
||||
write_fatal ();
|
||||
if (ferror (stdin) || fclose (stdin) != 0)
|
||||
@ -195,7 +200,11 @@ there_is_another_patch()
|
||||
return FALSE;
|
||||
}
|
||||
if (skip_rest_of_patch)
|
||||
{
|
||||
Fseek (pfp, p_start, SEEK_SET);
|
||||
p_input_line = p_sline - 1;
|
||||
return TRUE;
|
||||
}
|
||||
if (verbosity == VERBOSE)
|
||||
say (" %sooks like %s to me...\n",
|
||||
(p_base == 0 ? "L" : "The next patch l"),
|
||||
@ -204,21 +213,32 @@ there_is_another_patch()
|
||||
diff_type == NEW_CONTEXT_DIFF ? "a new-style context diff" :
|
||||
diff_type == NORMAL_DIFF ? "a normal diff" :
|
||||
"an ed script" );
|
||||
if (p_indent && verbosity != SILENT)
|
||||
say ("(Patch is indented %d space%s.)\n", p_indent, p_indent==1?"":"s");
|
||||
|
||||
if (verbosity != SILENT)
|
||||
{
|
||||
if (p_indent)
|
||||
say ("(Patch is indented %d space%s.)\n", p_indent, p_indent==1?"":"s");
|
||||
if (! inname)
|
||||
say ("can't find file to patch at input line %ld\n",
|
||||
p_sline);
|
||||
}
|
||||
|
||||
skip_to(p_start,p_sline);
|
||||
while (!inname) {
|
||||
if (force || batch) {
|
||||
say ("No file to patch. Skipping...\n");
|
||||
say ("No file to patch. Skipping patch.\n");
|
||||
skip_rest_of_patch = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
ask ("File to patch: ");
|
||||
inname = fetchname (buf, 0, (int *) 0);
|
||||
inname = fetchname (buf, 0, (time_t *) 0);
|
||||
if (inname)
|
||||
{
|
||||
if (stat (inname, &instat) == 0)
|
||||
inerrno = 0;
|
||||
{
|
||||
inerrno = 0;
|
||||
invc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror (inname);
|
||||
@ -230,7 +250,7 @@ there_is_another_patch()
|
||||
ask ("Skip this patch? [y] ");
|
||||
if (*buf != 'n') {
|
||||
if (verbosity != SILENT)
|
||||
say ("Skipping patch...\n");
|
||||
say ("Skipping patch.\n");
|
||||
skip_rest_of_patch = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
@ -259,11 +279,14 @@ intuit_diff_type()
|
||||
char *name[3];
|
||||
struct stat st[3];
|
||||
int stat_errno[3];
|
||||
int version_controlled[3];
|
||||
register enum diff retval;
|
||||
int head_says_nonexistent[2];
|
||||
|
||||
name[OLD] = name[NEW] = name[INDEX] = 0;
|
||||
head_says_nonexistent[OLD] = head_says_nonexistent[NEW] = 0;
|
||||
version_controlled[OLD] = -1;
|
||||
version_controlled[NEW] = -1;
|
||||
version_controlled[INDEX] = -1;
|
||||
p_timestamp[OLD] = p_timestamp[NEW] = (time_t) -1;
|
||||
p_says_nonexistent[OLD] = p_says_nonexistent[NEW] = 0;
|
||||
Fseek (pfp, p_base, SEEK_SET);
|
||||
p_input_line = p_bline - 1;
|
||||
@ -304,14 +327,14 @@ intuit_diff_type()
|
||||
p_indent = indent; /* assume this for now */
|
||||
}
|
||||
if (!stars_last_line && strnEQ(s, "*** ", 4))
|
||||
name[OLD] = fetchname (s+4, strippath, &head_says_nonexistent[OLD]);
|
||||
name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]);
|
||||
else if (strnEQ(s, "--- ", 4))
|
||||
name[NEW] = fetchname (s+4, strippath, &head_says_nonexistent[NEW]);
|
||||
name[NEW] = fetchname (s+4, strippath, &p_timestamp[NEW]);
|
||||
else if (strnEQ(s, "+++ ", 4))
|
||||
/* Swap with NEW below. */
|
||||
name[OLD] = fetchname (s+4, strippath, &head_says_nonexistent[OLD]);
|
||||
name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]);
|
||||
else if (strnEQ(s, "Index:", 6))
|
||||
name[INDEX] = fetchname (s+6, strippath, (int *) 0);
|
||||
name[INDEX] = fetchname (s+6, strippath, (time_t *) 0);
|
||||
else if (strnEQ(s, "Prereq:", 7)) {
|
||||
for (t = s + 7; ISSPACE ((unsigned char) *t); t++)
|
||||
continue;
|
||||
@ -338,24 +361,32 @@ intuit_diff_type()
|
||||
}
|
||||
if ((diff_type == NO_DIFF || diff_type == UNI_DIFF)
|
||||
&& strnEQ(s, "@@ -", 4)) {
|
||||
s += 4;
|
||||
/* `name' and `head_says_nonexistent' are backwards.
|
||||
Swap the former, and interpret the latter backwards. */
|
||||
|
||||
/* `name' and `p_timestamp' are backwards; swap them. */
|
||||
time_t ti = p_timestamp[OLD];
|
||||
p_timestamp[OLD] = p_timestamp[NEW];
|
||||
p_timestamp[NEW] = ti;
|
||||
t = name[OLD];
|
||||
name[OLD] = name[NEW];
|
||||
name[NEW] = t;
|
||||
if (head_says_nonexistent[NEW] && ! atol (s))
|
||||
p_says_nonexistent[OLD] = 1;
|
||||
|
||||
s += 4;
|
||||
if (! atol (s))
|
||||
p_says_nonexistent[OLD] = 1 + ! p_timestamp[OLD];
|
||||
while (*s != ' ' && *s != '\n')
|
||||
s++;
|
||||
while (*s == ' ')
|
||||
s++;
|
||||
if (head_says_nonexistent[OLD] && ! atol (s))
|
||||
p_says_nonexistent[NEW] = 1;
|
||||
if (! atol (s))
|
||||
p_says_nonexistent[NEW] = 1 + ! p_timestamp[NEW];
|
||||
p_indent = indent;
|
||||
p_start = this_line;
|
||||
p_sline = p_input_line;
|
||||
retval = UNI_DIFF;
|
||||
if (! ((name[OLD] || ! p_timestamp[OLD])
|
||||
&& (name[NEW] || ! p_timestamp[NEW])))
|
||||
say ("missing header for unified diff at line %ld of patch\n",
|
||||
p_sline);
|
||||
goto scan_exit;
|
||||
}
|
||||
stars_this_line = strnEQ(s, "********", 8);
|
||||
@ -364,8 +395,8 @@ intuit_diff_type()
|
||||
|| diff_type == NEW_CONTEXT_DIFF)
|
||||
&& stars_last_line && strnEQ (s, "*** ", 4)) {
|
||||
s += 4;
|
||||
if (head_says_nonexistent[OLD] && ! atol (s))
|
||||
p_says_nonexistent[OLD] = 1;
|
||||
if (! atol (s))
|
||||
p_says_nonexistent[OLD] = 1 + ! p_timestamp[OLD];
|
||||
/* if this is a new context diff the character just before */
|
||||
/* the newline is a '*'. */
|
||||
while (*s != '\n')
|
||||
@ -375,20 +406,23 @@ intuit_diff_type()
|
||||
p_sline = p_input_line - 1;
|
||||
retval = (*(s-1) == '*' ? NEW_CONTEXT_DIFF : CONTEXT_DIFF);
|
||||
|
||||
if (head_says_nonexistent[NEW])
|
||||
{
|
||||
/* Scan the first hunk to see whether the file appears to
|
||||
have been deleted. */
|
||||
file_offset saved_p_base = p_base;
|
||||
LINENUM saved_p_bline = p_bline;
|
||||
p_input_line = p_sline;
|
||||
Fseek (pfp, previous_line, SEEK_SET);
|
||||
if (another_hunk (retval, 0)
|
||||
&& ! p_repl_lines && p_newfirst == 1)
|
||||
p_says_nonexistent[NEW] = 1;
|
||||
next_intuit_at (saved_p_base, saved_p_bline);
|
||||
}
|
||||
{
|
||||
/* Scan the first hunk to see whether the file contents
|
||||
appear to have been deleted. */
|
||||
file_offset saved_p_base = p_base;
|
||||
LINENUM saved_p_bline = p_bline;
|
||||
Fseek (pfp, previous_line, SEEK_SET);
|
||||
p_input_line -= 2;
|
||||
if (another_hunk (retval, 0)
|
||||
&& ! p_repl_lines && p_newfirst == 1)
|
||||
p_says_nonexistent[NEW] = 1 + ! p_timestamp[NEW];
|
||||
next_intuit_at (saved_p_base, saved_p_bline);
|
||||
}
|
||||
|
||||
if (! ((name[OLD] || ! p_timestamp[OLD])
|
||||
&& (name[NEW] || ! p_timestamp[NEW])))
|
||||
say ("missing header for context diff at line %ld of patch\n",
|
||||
p_sline);
|
||||
goto scan_exit;
|
||||
}
|
||||
if ((diff_type == NO_DIFF || diff_type == NORMAL_DIFF) &&
|
||||
@ -409,12 +443,18 @@ intuit_diff_type()
|
||||
(with some modifications if posixly_correct is zero):
|
||||
|
||||
- Take the old and new names from the context header if present,
|
||||
and take the index name from the `Index:' line if present.
|
||||
and take the index name from the `Index:' line if present and
|
||||
if either the old and new names are both absent
|
||||
or posixly_correct is nonzero.
|
||||
Consider the file names to be in the order (old, new, index).
|
||||
- If some named files exist, use the first one if posixly_correct
|
||||
is nonzero, the best one otherwise.
|
||||
- If no named files exist, some names are given, posixly_correct is
|
||||
zero, and the patch appears to create a file, then use the best name
|
||||
- If patch_get is nonzero, and no named files exist,
|
||||
but an RCS or SCCS master file exists,
|
||||
use the first named file with an RCS or SCCS master.
|
||||
- If no named files exist, no RCS or SCCS master was found,
|
||||
some names are given, posixly_correct is zero,
|
||||
and the patch appears to create a file, then use the best name
|
||||
requiring the creation of the fewest directories.
|
||||
- Otherwise, report failure by setting `inname' to 0;
|
||||
this causes our invoker to ask the user for a file name. */
|
||||
@ -425,6 +465,12 @@ intuit_diff_type()
|
||||
{
|
||||
enum nametype i0 = NONE;
|
||||
|
||||
if (! posixly_correct && (name[OLD] || name[NEW]) && name[INDEX])
|
||||
{
|
||||
free (name[INDEX]);
|
||||
name[INDEX] = 0;
|
||||
}
|
||||
|
||||
for (i = OLD; i <= INDEX; i++)
|
||||
if (name[i])
|
||||
{
|
||||
@ -450,15 +496,57 @@ intuit_diff_type()
|
||||
{
|
||||
i = best_name (name, stat_errno);
|
||||
|
||||
if (p_says_nonexistent[reverse ^ (i == NONE)])
|
||||
if (i == NONE && patch_get)
|
||||
{
|
||||
enum nametype nope = NONE;
|
||||
|
||||
for (i = OLD; i <= INDEX; i++)
|
||||
if (name[i])
|
||||
{
|
||||
char const *cs;
|
||||
char *getbuf;
|
||||
char *diffbuf;
|
||||
int readonly = outfile && strcmp (outfile, name[i]) != 0;
|
||||
|
||||
if (nope == NONE || strcmp (name[nope], name[i]) != 0)
|
||||
{
|
||||
cs = (version_controller
|
||||
(name[i], readonly, (struct stat *) 0,
|
||||
&getbuf, &diffbuf));
|
||||
version_controlled[i] = !! cs;
|
||||
if (cs)
|
||||
{
|
||||
if (version_get (name[i], cs, 0, readonly,
|
||||
getbuf, &st[i]))
|
||||
stat_errno[i] = 0;
|
||||
else
|
||||
version_controlled[i] = 0;
|
||||
|
||||
free (getbuf);
|
||||
free (diffbuf);
|
||||
|
||||
if (! stat_errno[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nope = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_says_nonexistent[reverse ^ (i == NONE || st[i].st_size == 0)])
|
||||
{
|
||||
assert (i0 != NONE);
|
||||
if (ok_to_reverse
|
||||
("The next patch%s would %s the file `%s',\nwhich %s!",
|
||||
reverse ? ", when reversed," : "",
|
||||
i == NONE ? "delete" : "create",
|
||||
name[i == NONE ? i0 : i],
|
||||
i == NONE ? "does not exist" : "already exists"))
|
||||
(i == NONE ? "delete"
|
||||
: st[i].st_size == 0 ? "empty out"
|
||||
: "create"),
|
||||
name[i == NONE || st[i].st_size == 0 ? i0 : i],
|
||||
(i == NONE ? "does not exist"
|
||||
: st[i].st_size == 0 ? "is already empty"
|
||||
: "already exists")))
|
||||
reverse ^= 1;
|
||||
}
|
||||
|
||||
@ -493,6 +581,7 @@ intuit_diff_type()
|
||||
inname = name[i];
|
||||
name[i] = 0;
|
||||
inerrno = stat_errno[i];
|
||||
invc = version_controlled[i];
|
||||
instat = st[i];
|
||||
}
|
||||
|
||||
@ -1533,7 +1622,8 @@ pch_swap()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Return whether file WHICH (0 = old, 1 = new) appears to be nonexistent. */
|
||||
/* Return whether file WHICH (0 = old, 1 = new) appears to nonexistent.
|
||||
Return 1 for empty, 2 for nonexistent. */
|
||||
|
||||
bool
|
||||
pch_says_nonexistent (which)
|
||||
@ -1542,6 +1632,16 @@ pch_says_nonexistent (which)
|
||||
return p_says_nonexistent[which];
|
||||
}
|
||||
|
||||
/* Return timestamp of patch header for file WHICH (0 = old, 1 = new),
|
||||
or -1 if there was no timestamp or an error in the timestamp. */
|
||||
|
||||
time_t
|
||||
pch_timestamp (which)
|
||||
int which;
|
||||
{
|
||||
return p_timestamp[which];
|
||||
}
|
||||
|
||||
/* Return the specified line position in the old file of the old context. */
|
||||
|
||||
LINENUM
|
||||
@ -1665,6 +1765,7 @@ do_ed_script (ofp)
|
||||
copy_file (inname, TMPOUTNAME, instat.st_mode);
|
||||
sprintf (buf, "%s %s%s", ed_program, verbosity == VERBOSE ? "" : "- ",
|
||||
TMPOUTNAME);
|
||||
fflush (stdout);
|
||||
pipefp = popen(buf, binary_transput ? "wb" : "w");
|
||||
if (!pipefp)
|
||||
pfatal ("can't open pipe to `%s'", buf);
|
||||
|
||||
3
pch.h
3
pch.h
@ -1,6 +1,6 @@
|
||||
/* reading patches */
|
||||
|
||||
/* $Id: pch.h,v 1.7 1997/05/19 06:52:03 eggert Exp $ */
|
||||
/* $Id: pch.h,v 1.8 1997/06/13 06:28:37 eggert Exp $ */
|
||||
|
||||
LINENUM pch_end PARAMS ((void));
|
||||
LINENUM pch_first PARAMS ((void));
|
||||
@ -18,6 +18,7 @@ char pch_char PARAMS ((LINENUM));
|
||||
int another_hunk PARAMS ((enum diff, int));
|
||||
int pch_says_nonexistent PARAMS ((int));
|
||||
size_t pch_line_len PARAMS ((LINENUM));
|
||||
time_t pch_timestamp PARAMS ((int));
|
||||
void do_ed_script PARAMS ((FILE *));
|
||||
void open_patch_file PARAMS ((char const *));
|
||||
void re_patch PARAMS ((void));
|
||||
|
||||
297
util.c
297
util.c
@ -1,6 +1,6 @@
|
||||
/* utility functions for `patch' */
|
||||
|
||||
/* $Id: util.c,v 1.17 1997/05/30 08:03:48 eggert Exp $ */
|
||||
/* $Id: util.c,v 1.22 1997/06/13 06:28:37 eggert Exp $ */
|
||||
|
||||
/*
|
||||
Copyright 1986 Larry Wall
|
||||
@ -25,18 +25,22 @@ If not, write to the Free Software Foundation,
|
||||
#define XTERN extern
|
||||
#include <common.h>
|
||||
#include <backupfile.h>
|
||||
#include <quotearg.h>
|
||||
#include <version.h>
|
||||
#undef XTERN
|
||||
#define XTERN
|
||||
#include <util.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <maketime.h>
|
||||
#include <partime.h>
|
||||
|
||||
#include <signal.h>
|
||||
#if !defined SIGCHLD && defined SIGCLD
|
||||
#define SIGCHLD SIGCLD
|
||||
#endif
|
||||
#if ! HAVE_RAISE
|
||||
# define raise(sig) kill (getpid (), sig)
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <stdarg.h>
|
||||
@ -77,7 +81,7 @@ move_file (from, to, mode, backup)
|
||||
struct stat to_st;
|
||||
int to_errno = ! backup ? -1 : stat (to, &to_st) == 0 ? 0 : errno;
|
||||
|
||||
if (! to_errno)
|
||||
if (backup)
|
||||
{
|
||||
int try_makedirs_errno = 0;
|
||||
char *bakname;
|
||||
@ -110,15 +114,36 @@ move_file (from, to, mode, backup)
|
||||
memory_fatal ();
|
||||
}
|
||||
|
||||
if (debug & 4)
|
||||
say ("renaming `%s' to `%s'\n", to, bakname);
|
||||
while (rename (to, bakname) != 0)
|
||||
if (to_errno)
|
||||
{
|
||||
if (errno != try_makedirs_errno)
|
||||
pfatal ("can't rename `%s' to `%s'", to, bakname);
|
||||
makedirs (bakname);
|
||||
try_makedirs_errno = 0;
|
||||
int fd;
|
||||
if (debug & 4)
|
||||
say ("creating empty unreadable file `%s'\n", bakname);
|
||||
try_makedirs_errno = ENOENT;
|
||||
unlink (bakname);
|
||||
while ((fd = creat (bakname, 0)) < 0)
|
||||
{
|
||||
if (errno != try_makedirs_errno)
|
||||
pfatal ("can't create file `%s'", bakname);
|
||||
makedirs (bakname);
|
||||
try_makedirs_errno = 0;
|
||||
}
|
||||
if (close (fd) != 0)
|
||||
pfatal ("can't close `%s'", bakname);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug & 4)
|
||||
say ("renaming `%s' to `%s'\n", to, bakname);
|
||||
while (rename (to, bakname) != 0)
|
||||
{
|
||||
if (errno != try_makedirs_errno)
|
||||
pfatal ("can't rename `%s' to `%s'", to, bakname);
|
||||
makedirs (bakname);
|
||||
try_makedirs_errno = 0;
|
||||
}
|
||||
}
|
||||
|
||||
free (bakname);
|
||||
}
|
||||
|
||||
@ -218,6 +243,159 @@ copy_file (from, to, mode)
|
||||
write_fatal ();
|
||||
}
|
||||
|
||||
static char const DEV_NULL[] = NULL_DEVICE;
|
||||
|
||||
static char const SCCSPREFIX[] = "s.";
|
||||
static char const GET[] = "get ";
|
||||
static char const GET_LOCKED[] = "get -e ";
|
||||
static char const SCCSDIFF1[] = "get -p ";
|
||||
static char const SCCSDIFF2[] = "|diff - %s";
|
||||
|
||||
static char const RCSSUFFIX[] = ",v";
|
||||
static char const CHECKOUT[] = "co %s";
|
||||
static char const CHECKOUT_LOCKED[] = "co -l %s";
|
||||
static char const RCSDIFF1[] = "rcsdiff %s";
|
||||
|
||||
/* Return "RCS" if FILENAME is controlled by RCS,
|
||||
"SCCS" if it is controlled by SCCS, and 0 otherwise.
|
||||
READONLY is nonzero if we desire only readonly access to FILENAME.
|
||||
FILESTAT describes FILENAME's status or is 0 if FILENAME does not exist.
|
||||
If successful and if GETBUF is nonzero, set *GETBUF to a command
|
||||
that gets the file; similarly for DIFFBUF and a command to diff the file.
|
||||
*GETBUF and *DIFFBUF must be freed by the caller. */
|
||||
char const *
|
||||
version_controller (filename, readonly, filestat, getbuf, diffbuf)
|
||||
char const *filename;
|
||||
int readonly;
|
||||
struct stat const *filestat;
|
||||
char **getbuf;
|
||||
char **diffbuf;
|
||||
{
|
||||
struct stat cstat;
|
||||
char const *filebase = base_name (filename);
|
||||
char const *dotslash = *filename == '-' ? "./" : "";
|
||||
size_t dir_len = filebase - filename;
|
||||
size_t filenamelen = strlen (filename);
|
||||
size_t maxfixlen = sizeof "SCCS/" - 1 + sizeof SCCSPREFIX - 1;
|
||||
size_t maxtrysize = filenamelen + maxfixlen + 1;
|
||||
size_t quotelen = quote_system_arg (0, filename);
|
||||
size_t maxgetsize = sizeof GET_LOCKED + quotelen + maxfixlen;
|
||||
size_t maxdiffsize =
|
||||
(sizeof SCCSDIFF1 + sizeof SCCSDIFF2 + sizeof DEV_NULL - 1
|
||||
+ 2 * quotelen + maxfixlen);
|
||||
char *trybuf = xmalloc (maxtrysize);
|
||||
char const *r = 0;
|
||||
|
||||
strcpy (trybuf, filename);
|
||||
|
||||
#define try1(f,a1) (sprintf (trybuf + dir_len, f, a1), stat (trybuf, &cstat) == 0)
|
||||
#define try2(f,a1,a2) (sprintf (trybuf + dir_len, f, a1,a2), stat (trybuf, &cstat) == 0)
|
||||
|
||||
/* Check that RCS file is not working file.
|
||||
Some hosts don't report file name length errors. */
|
||||
|
||||
if ((try2 ("RCS/%s%s", filebase, RCSSUFFIX)
|
||||
|| try1 ("RCS/%s", filebase)
|
||||
|| try2 ("%s%s", filebase, RCSSUFFIX))
|
||||
&& ! (filestat
|
||||
&& filestat->st_dev == cstat.st_dev
|
||||
&& filestat->st_ino == cstat.st_ino))
|
||||
{
|
||||
if (getbuf)
|
||||
{
|
||||
char *p = *getbuf = xmalloc (maxgetsize);
|
||||
sprintf (p, readonly ? CHECKOUT : CHECKOUT_LOCKED, dotslash);
|
||||
p += strlen (p);
|
||||
p += quote_system_arg (p, filename);
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
if (diffbuf)
|
||||
{
|
||||
char *p = *diffbuf = xmalloc (maxdiffsize);
|
||||
sprintf (p, RCSDIFF1, dotslash);
|
||||
p += strlen (p);
|
||||
p += quote_system_arg (p, filename);
|
||||
*p++ = '>';
|
||||
strcpy (p, DEV_NULL);
|
||||
}
|
||||
|
||||
r = "RCS";
|
||||
}
|
||||
else if (try2 ("SCCS/%s%s", SCCSPREFIX, filebase)
|
||||
|| try2 ("%s%s", SCCSPREFIX, filebase))
|
||||
{
|
||||
if (getbuf)
|
||||
{
|
||||
char *p = *getbuf = xmalloc (maxgetsize);
|
||||
sprintf (p, readonly ? GET : GET_LOCKED);
|
||||
p += strlen (p);
|
||||
p += quote_system_arg (p, trybuf);
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
if (diffbuf)
|
||||
{
|
||||
char *p = *diffbuf = xmalloc (maxdiffsize);
|
||||
strcpy (p, SCCSDIFF1);
|
||||
p += sizeof SCCSDIFF1 - 1;
|
||||
p += quote_system_arg (p, trybuf);
|
||||
sprintf (p, SCCSDIFF2, dotslash);
|
||||
p += strlen (p);
|
||||
p += quote_system_arg (p, filename);
|
||||
*p++ = '>';
|
||||
strcpy (p, DEV_NULL);
|
||||
}
|
||||
|
||||
r = "SCCS";
|
||||
}
|
||||
|
||||
free (trybuf);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Get FILENAME from version control system CS. The file already exists if
|
||||
EXISTS is nonzero. Only readonly access is needed if READONLY is nonzero.
|
||||
Use the command GETBUF to actually get the named file.
|
||||
Store the resulting file status into *FILESTAT.
|
||||
Return nonzero if successful. */
|
||||
int
|
||||
version_get (filename, cs, exists, readonly, getbuf, filestat)
|
||||
char const *filename;
|
||||
char const *cs;
|
||||
int exists;
|
||||
int readonly;
|
||||
char const *getbuf;
|
||||
struct stat *filestat;
|
||||
{
|
||||
if (patch_get < 0)
|
||||
{
|
||||
ask ("Get file `%s' from %s%s? [y] ", filename,
|
||||
cs, readonly ? "" : " with lock");
|
||||
if (*buf == 'n')
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dry_run)
|
||||
{
|
||||
if (! exists)
|
||||
fatal ("can't do dry run on nonexistent version-controlled file `%s'; invoke `%s' and try again",
|
||||
filename, getbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbosity == VERBOSE)
|
||||
say ("Getting file `%s' from %s%s...\n", filename,
|
||||
cs, readonly ? "" : " with lock");
|
||||
if (systemic (getbuf) != 0)
|
||||
fatal ("can't get file `%s' from %s", filename, cs);
|
||||
if (stat (filename, filestat) != 0)
|
||||
pfatal ("%s", filename);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Allocate a unique area for a string. */
|
||||
|
||||
char *
|
||||
@ -339,7 +517,7 @@ pfatal (format, va_alist)
|
||||
vararg_start (args, format);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
fflush (stderr);
|
||||
fflush (stderr); /* perror bypasses stdio on some hosts. */
|
||||
errno = errnum;
|
||||
perror (" ");
|
||||
fflush (stderr);
|
||||
@ -388,21 +566,22 @@ ask (format, va_alist)
|
||||
|
||||
if (ttyfd == -2)
|
||||
{
|
||||
ttyfd = open ("/dev/tty", O_RDONLY);
|
||||
if (ttyfd < 0)
|
||||
{
|
||||
close (ttyfd);
|
||||
for (ttyfd = STDERR_FILENO; 0 <= ttyfd; ttyfd--)
|
||||
if (isatty (ttyfd))
|
||||
break;
|
||||
}
|
||||
/* If standard output is not a tty, don't bother opening /dev/tty,
|
||||
since it's unlikely that stdout will be seen by the tty user.
|
||||
The isatty test also works around a bug in GNU Emacs 19.34 under Linux
|
||||
which makes a call-process `patch' hang when it reads from /dev/tty.
|
||||
POSIX.2 requires that we read /dev/tty, though. */
|
||||
ttyfd = (posixly_correct || isatty (STDOUT_FILENO)
|
||||
? open (TTY_DEVICE, O_RDONLY)
|
||||
: -1);
|
||||
}
|
||||
|
||||
if (ttyfd < 0)
|
||||
{
|
||||
/* No terminal at all -- default it. */
|
||||
printf ("\n");
|
||||
buf[0] = '\n';
|
||||
r = 1;
|
||||
buf[1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -420,13 +599,14 @@ ask (format, va_alist)
|
||||
printf ("EOF\n");
|
||||
else if (r < 0)
|
||||
{
|
||||
perror ("tty read");
|
||||
fflush (stderr);
|
||||
close (ttyfd);
|
||||
ttyfd = -1;
|
||||
r = 0;
|
||||
}
|
||||
buf[s + r] = '\0';
|
||||
}
|
||||
|
||||
buf[r] = '\0';
|
||||
}
|
||||
|
||||
/* Return nonzero if it OK to reverse a patch. */
|
||||
@ -442,7 +622,7 @@ ok_to_reverse (format, va_alist)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if (noreverse || ! batch || verbosity != SILENT)
|
||||
if (noreverse || ! (force && verbosity == SILENT))
|
||||
{
|
||||
va_list args;
|
||||
vararg_start (args, format);
|
||||
@ -452,14 +632,19 @@ ok_to_reverse (format, va_alist)
|
||||
|
||||
if (noreverse)
|
||||
{
|
||||
printf (" Ignoring it.\n");
|
||||
printf (" Skipping patch.\n");
|
||||
skip_rest_of_patch = TRUE;
|
||||
r = 0;
|
||||
}
|
||||
else if (force)
|
||||
{
|
||||
if (verbosity != SILENT)
|
||||
printf (" Applying it anyway.\n");
|
||||
r = 0;
|
||||
}
|
||||
else if (batch)
|
||||
{
|
||||
if (verbosity != SILENT)
|
||||
say (reverse ? " Ignoring -R.\n" : " Assuming -R.\n");
|
||||
say (reverse ? " Ignoring -R.\n" : " Assuming -R.\n");
|
||||
r = 1;
|
||||
}
|
||||
else
|
||||
@ -470,7 +655,11 @@ ok_to_reverse (format, va_alist)
|
||||
{
|
||||
ask ("Apply anyway? [n] ");
|
||||
if (*buf != 'y')
|
||||
skip_rest_of_patch = TRUE;
|
||||
{
|
||||
if (verbosity != SILENT)
|
||||
say ("Skipping patch.\n");
|
||||
skip_rest_of_patch = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -484,6 +673,9 @@ static int const sigs[] = {
|
||||
#ifdef SIGHUP
|
||||
SIGHUP,
|
||||
#endif
|
||||
#ifdef SIGPIPE
|
||||
SIGPIPE,
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
SIGTERM,
|
||||
#endif
|
||||
@ -493,8 +685,7 @@ static int const sigs[] = {
|
||||
#ifdef SIGXFSZ
|
||||
SIGXFSZ,
|
||||
#endif
|
||||
SIGINT,
|
||||
SIGPIPE
|
||||
SIGINT
|
||||
};
|
||||
|
||||
#if !HAVE_SIGPROCMASK
|
||||
@ -616,7 +807,7 @@ exit_with_signal (sig)
|
||||
sigemptyset (&s);
|
||||
sigaddset (&s, sig);
|
||||
sigprocmask (SIG_UNBLOCK, &s, (sigset_t *) 0);
|
||||
kill (getpid (), sig);
|
||||
raise (sig);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
@ -626,6 +817,7 @@ systemic (command)
|
||||
{
|
||||
if (debug & 8)
|
||||
say ("+ %s\n", command);
|
||||
fflush (stdout);
|
||||
return system (command);
|
||||
}
|
||||
|
||||
@ -633,7 +825,6 @@ systemic (command)
|
||||
/* These mkdir and rmdir substitutes are good enough for `patch';
|
||||
they are not general emulators. */
|
||||
|
||||
#include <quotearg.h>
|
||||
static int doprogram PARAMS ((char const *, char const *));
|
||||
static int mkdir PARAMS ((char const *, mode_t));
|
||||
static int rmdir PARAMS ((char const *));
|
||||
@ -793,18 +984,16 @@ init_time ()
|
||||
/* Make filenames more reasonable. */
|
||||
|
||||
char *
|
||||
fetchname (at, strip_leading, head_says_nonexistent)
|
||||
fetchname (at, strip_leading, pstamp)
|
||||
char *at;
|
||||
int strip_leading;
|
||||
int *head_says_nonexistent;
|
||||
time_t *pstamp;
|
||||
{
|
||||
char *name;
|
||||
register char *t;
|
||||
int sleading = strip_leading;
|
||||
int says_nonexistent = 0;
|
||||
time_t stamp = (time_t) -1;
|
||||
|
||||
if (!at)
|
||||
return 0;
|
||||
while (ISSPACE ((unsigned char) *at))
|
||||
at++;
|
||||
if (debug & 128)
|
||||
@ -823,15 +1012,21 @@ int *head_says_nonexistent;
|
||||
}
|
||||
else if (ISSPACE ((unsigned char) *t))
|
||||
{
|
||||
/* The head says the file is nonexistent if the timestamp
|
||||
is the epoch; but the listed time is local time, not UTC,
|
||||
and POSIX.1 allows local time to be 24 hours away from UTC.
|
||||
So match any time within 24 hours of the epoch.
|
||||
Use a default time zone 24 hours behind UTC so that any
|
||||
non-zoned time within 24 hours of the epoch is valid. */
|
||||
time_t stamp = str2time (t, initial_time, -24L * 60 * 60);
|
||||
if (0 <= stamp && stamp <= 2 * 24L * 60 * 60)
|
||||
says_nonexistent = 1;
|
||||
if (set_time | set_utc)
|
||||
stamp = str2time (t, initial_time, set_utc ? 0L : TM_LOCAL_ZONE);
|
||||
else
|
||||
{
|
||||
/* The head says the file is nonexistent if the timestamp
|
||||
is the epoch; but the listed time is local time, not UTC,
|
||||
and POSIX.1 allows local time to be 24 hours away from UTC.
|
||||
So match any time within 24 hours of the epoch.
|
||||
Use a default time zone 24 hours behind UTC so that any
|
||||
non-zoned time within 24 hours of the epoch is valid. */
|
||||
stamp = str2time (t, initial_time, -24L * 60 * 60);
|
||||
if (0 <= stamp && stamp <= 2 * 24L * 60 * 60)
|
||||
stamp = 0;
|
||||
}
|
||||
|
||||
*t = '\0';
|
||||
break;
|
||||
}
|
||||
@ -843,22 +1038,22 @@ int *head_says_nonexistent;
|
||||
/* Allow files to be created by diffing against /dev/null. */
|
||||
if (strcmp (at, "/dev/null") == 0)
|
||||
{
|
||||
if (head_says_nonexistent)
|
||||
*head_says_nonexistent = 1;
|
||||
if (pstamp)
|
||||
*pstamp = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (head_says_nonexistent)
|
||||
*head_says_nonexistent = says_nonexistent;
|
||||
if (pstamp)
|
||||
*pstamp = stamp;
|
||||
|
||||
return savestr (name);
|
||||
}
|
||||
|
||||
VOID *
|
||||
GENERIC_OBJECT *
|
||||
xmalloc (size)
|
||||
size_t size;
|
||||
{
|
||||
register VOID *p = malloc (size);
|
||||
register GENERIC_OBJECT *p = malloc (size);
|
||||
if (!p)
|
||||
memory_fatal ();
|
||||
return p;
|
||||
|
||||
6
util.h
6
util.h
@ -1,6 +1,6 @@
|
||||
/* utility functions for `patch' */
|
||||
|
||||
/* $Id: util.h,v 1.12 1997/05/19 06:52:03 eggert Exp $ */
|
||||
/* $Id: util.h,v 1.14 1997/06/13 06:28:37 eggert Exp $ */
|
||||
|
||||
int ok_to_reverse PARAMS ((char const *, ...)) __attribute__ ((format (printf, 1, 2)));
|
||||
void ask PARAMS ((char const *, ...)) __attribute__ ((format (printf, 1, 2)));
|
||||
@ -11,9 +11,11 @@ void fatal PARAMS ((char const *, ...))
|
||||
void pfatal PARAMS ((char const *, ...))
|
||||
__attribute__ ((noreturn, format (printf, 1, 2)));
|
||||
|
||||
char *fetchname PARAMS ((char *, int, int *));
|
||||
char *fetchname PARAMS ((char *, int, time_t *));
|
||||
char *savebuf PARAMS ((char const *, size_t));
|
||||
char *savestr PARAMS ((char const *));
|
||||
char const *version_controller PARAMS ((char const *, int, struct stat const *, char **, char **));
|
||||
int version_get PARAMS ((char const *, char const *, int, int, char const *, struct stat *));
|
||||
int create_file PARAMS ((char const *, int, mode_t));
|
||||
int systemic PARAMS ((char const *));
|
||||
void Fseek PARAMS ((FILE *, file_offset, int));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user