mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-04 10:19:26 +00:00
Resurrect patch 2.1 without FreeBSD Index: hack
This commit is contained in:
parent
4d834db441
commit
249a716c6c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=32672
27
gnu/usr.bin/patch/EXTERN.h
Normal file
27
gnu/usr.bin/patch/EXTERN.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* $Header: /home/ncvs/src/gnu/usr.bin/patch/EXTERN.h,v 1.2 1995/05/30 05:02:26 rgrimes Exp $
|
||||
*
|
||||
* $Log: EXTERN.h,v $
|
||||
* Revision 1.2 1995/05/30 05:02:26 rgrimes
|
||||
* Remove trailing whitespace.
|
||||
*
|
||||
* Revision 1.1.1.1 1993/06/19 14:21:52 paul
|
||||
* b-maked patch-2.10
|
||||
*
|
||||
* Revision 2.0 86/09/17 15:35:37 lwall
|
||||
* Baseline for netwide release.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef EXT
|
||||
#undef EXT
|
||||
#endif
|
||||
#define EXT extern
|
||||
|
||||
#ifdef INIT
|
||||
#undef INIT
|
||||
#endif
|
||||
#define INIT(x)
|
||||
|
||||
#ifdef DOINIT
|
||||
#undef DOINIT
|
||||
#endif
|
25
gnu/usr.bin/patch/INTERN.h
Normal file
25
gnu/usr.bin/patch/INTERN.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* $Header: /home/ncvs/src/gnu/usr.bin/patch/INTERN.h,v 1.2 1995/05/30 05:02:27 rgrimes Exp $
|
||||
*
|
||||
* $Log: INTERN.h,v $
|
||||
* Revision 1.2 1995/05/30 05:02:27 rgrimes
|
||||
* Remove trailing whitespace.
|
||||
*
|
||||
* Revision 1.1.1.1 1993/06/19 14:21:52 paul
|
||||
* b-maked patch-2.10
|
||||
*
|
||||
* Revision 2.0 86/09/17 15:35:58 lwall
|
||||
* Baseline for netwide release.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef EXT
|
||||
#undef EXT
|
||||
#endif
|
||||
#define EXT
|
||||
|
||||
#ifdef INIT
|
||||
#undef INIT
|
||||
#endif
|
||||
#define INIT(x) = x
|
||||
|
||||
#define DOINIT
|
@ -1,16 +1,6 @@
|
||||
# $Id: Makefile,v 1.9 1997/10/29 17:35:54 ache Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/../../../contrib/patch
|
||||
|
||||
PROG= patch
|
||||
|
||||
LIBSRCS = getopt.c getopt1.c
|
||||
SRCS = addext.c argmatch.c backupfile.c basename.c inp.c maketime.c \
|
||||
partime.c patch.c pch.c quotearg.c util.c version.c $(LIBSRCS)
|
||||
|
||||
CFLAGS+= -I${.CURDIR}
|
||||
CFLAGS+= -I${.CURDIR}/../../../contrib/patch
|
||||
CFLAGS+= -DHAVE_CONFIG_H
|
||||
CFLAGS+= -Ded_PROGRAM=\"/bin/ed\"
|
||||
|
||||
SRCS = backupfile.c getopt.c getopt1.c inp.c patch.c pch.c util.c \
|
||||
version.c
|
||||
CFLAGS += -DHAVE_CONFIG_H
|
||||
MAN= patch.1
|
||||
.include <bsd.prog.mk>
|
||||
|
402
gnu/usr.bin/patch/backupfile.c
Normal file
402
gnu/usr.bin/patch/backupfile.c
Normal file
@ -0,0 +1,402 @@
|
||||
/* backupfile.c -- make Emacs style backup file names
|
||||
Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.
|
||||
Some algorithms adapted from GNU Emacs. */
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include "backupfile.h"
|
||||
#ifdef STDC_HEADERS
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *malloc ();
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(DIRENT) || defined(_POSIX_VERSION)
|
||||
#include <dirent.h>
|
||||
#define NLENGTH(direct) (strlen((direct)->d_name))
|
||||
#else /* not (DIRENT or _POSIX_VERSION) */
|
||||
#define dirent direct
|
||||
#define NLENGTH(direct) ((direct)->d_namlen)
|
||||
#ifdef SYSNDIR
|
||||
#include <sys/ndir.h>
|
||||
#endif /* SYSNDIR */
|
||||
#ifdef SYSDIR
|
||||
#include <sys/dir.h>
|
||||
#endif /* SYSDIR */
|
||||
#ifdef NDIR
|
||||
#include <ndir.h>
|
||||
#endif /* NDIR */
|
||||
#endif /* DIRENT or _POSIX_VERSION */
|
||||
|
||||
#ifndef isascii
|
||||
#define ISDIGIT(c) (isdigit ((unsigned char) (c)))
|
||||
#else
|
||||
#define ISDIGIT(c) (isascii (c) && isdigit (c))
|
||||
#endif
|
||||
|
||||
#if defined (_POSIX_VERSION)
|
||||
/* POSIX does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
#define REAL_DIR_ENTRY(dp) 1
|
||||
#else
|
||||
#define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
|
||||
#endif
|
||||
|
||||
/* Which type of backup file names are generated. */
|
||||
enum backup_type backup_type = none;
|
||||
|
||||
/* The extension added to file names to produce a simple (as opposed
|
||||
to numbered) backup file name. */
|
||||
char *simple_backup_suffix = "~";
|
||||
|
||||
char *basename ();
|
||||
char *dirname ();
|
||||
static char *concat ();
|
||||
char *find_backup_file_name ();
|
||||
static char *make_version_name ();
|
||||
static int max_backup_version ();
|
||||
static int version_number ();
|
||||
|
||||
/* Return NAME with any leading path stripped off. */
|
||||
|
||||
char *
|
||||
basename (name)
|
||||
char *name;
|
||||
{
|
||||
char *r = name, *p = name;
|
||||
|
||||
while (*p)
|
||||
if (*p++ == '/')
|
||||
r = p;
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifndef NODIR
|
||||
/* 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. */
|
||||
|
||||
char *
|
||||
find_backup_file_name (file)
|
||||
char *file;
|
||||
{
|
||||
char *dir;
|
||||
char *base_versions;
|
||||
int highest_backup;
|
||||
|
||||
if (backup_type == simple)
|
||||
{
|
||||
char *s = malloc (strlen (file) + strlen (simple_backup_suffix) + 1);
|
||||
strcpy (s, file);
|
||||
addext (s, simple_backup_suffix, '~');
|
||||
return s;
|
||||
}
|
||||
base_versions = concat (basename (file), ".~");
|
||||
if (base_versions == 0)
|
||||
return 0;
|
||||
dir = dirname (file);
|
||||
if (dir == 0)
|
||||
{
|
||||
free (base_versions);
|
||||
return 0;
|
||||
}
|
||||
highest_backup = max_backup_version (base_versions, dir);
|
||||
free (base_versions);
|
||||
free (dir);
|
||||
if (backup_type == numbered_existing && highest_backup == 0)
|
||||
return concat (file, simple_backup_suffix);
|
||||
return make_version_name (file, highest_backup + 1);
|
||||
}
|
||||
|
||||
/* Return the number of the highest-numbered backup file for file
|
||||
FILE in directory DIR. If there are no numbered backups
|
||||
of FILE in DIR, or an error occurs reading DIR, return 0.
|
||||
FILE should already have ".~" appended to it. */
|
||||
|
||||
static int
|
||||
max_backup_version (file, dir)
|
||||
char *file, *dir;
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
int highest_version;
|
||||
int this_version;
|
||||
int file_name_length;
|
||||
|
||||
dirp = opendir (dir);
|
||||
if (!dirp)
|
||||
return 0;
|
||||
|
||||
highest_version = 0;
|
||||
file_name_length = strlen (file);
|
||||
|
||||
while ((dp = readdir (dirp)) != 0)
|
||||
{
|
||||
if (!REAL_DIR_ENTRY (dp) || NLENGTH (dp) <= file_name_length)
|
||||
continue;
|
||||
|
||||
this_version = version_number (file, dp->d_name, file_name_length);
|
||||
if (this_version > highest_version)
|
||||
highest_version = this_version;
|
||||
}
|
||||
closedir (dirp);
|
||||
return highest_version;
|
||||
}
|
||||
|
||||
/* Return a string, allocated with malloc, containing
|
||||
"FILE.~VERSION~". Return 0 if out of memory. */
|
||||
|
||||
static char *
|
||||
make_version_name (file, version)
|
||||
char *file;
|
||||
int version;
|
||||
{
|
||||
char *backup_name;
|
||||
|
||||
backup_name = malloc (strlen (file) + 16);
|
||||
if (backup_name == 0)
|
||||
return 0;
|
||||
sprintf (backup_name, "%s.~%d~", file, version);
|
||||
return backup_name;
|
||||
}
|
||||
|
||||
/* If BACKUP is a numbered backup of BASE, return its version number;
|
||||
otherwise return 0. BASE_LENGTH is the length of BASE.
|
||||
BASE should already have ".~" appended to it. */
|
||||
|
||||
static int
|
||||
version_number (base, backup, base_length)
|
||||
char *base;
|
||||
char *backup;
|
||||
int base_length;
|
||||
{
|
||||
int version;
|
||||
char *p;
|
||||
|
||||
version = 0;
|
||||
if (!strncmp (base, backup, base_length) && ISDIGIT (backup[base_length]))
|
||||
{
|
||||
for (p = &backup[base_length]; ISDIGIT (*p); ++p)
|
||||
version = version * 10 + *p - '0';
|
||||
if (p[0] != '~' || p[1])
|
||||
version = 0;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
/* Return the newly-allocated concatenation of STR1 and STR2.
|
||||
If out of memory, return 0. */
|
||||
|
||||
static char *
|
||||
concat (str1, str2)
|
||||
char *str1, *str2;
|
||||
{
|
||||
char *newstr;
|
||||
char str1_length = strlen (str1);
|
||||
|
||||
newstr = malloc (str1_length + strlen (str2) + 1);
|
||||
if (newstr == 0)
|
||||
return 0;
|
||||
strcpy (newstr, str1);
|
||||
strcpy (newstr + str1_length, str2);
|
||||
return newstr;
|
||||
}
|
||||
|
||||
/* Return the leading directories part of PATH,
|
||||
allocated with malloc. If out of memory, return 0.
|
||||
Assumes that trailing slashes have already been
|
||||
removed. */
|
||||
|
||||
char *
|
||||
dirname (path)
|
||||
char *path;
|
||||
{
|
||||
char *newpath;
|
||||
char *slash;
|
||||
int length; /* Length of result, not including NUL. */
|
||||
|
||||
slash = basename (path);
|
||||
if (slash == path)
|
||||
{
|
||||
/* File is in the current directory. */
|
||||
path = ".";
|
||||
length = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove any trailing slashes from result. */
|
||||
while (*--slash == '/' && slash > path)
|
||||
;
|
||||
|
||||
length = slash - path + 1;
|
||||
}
|
||||
newpath = malloc (length + 1);
|
||||
if (newpath == 0)
|
||||
return 0;
|
||||
strncpy (newpath, path, length);
|
||||
newpath[length] = 0;
|
||||
return newpath;
|
||||
}
|
||||
|
||||
/* If ARG is an unambiguous match for an element of the
|
||||
null-terminated array OPTLIST, return the index in OPTLIST
|
||||
of the matched element, else -1 if it does not match any element
|
||||
or -2 if it is ambiguous (is a prefix of more than one element). */
|
||||
|
||||
int
|
||||
argmatch (arg, optlist)
|
||||
char *arg;
|
||||
char **optlist;
|
||||
{
|
||||
int i; /* Temporary index in OPTLIST. */
|
||||
int arglen; /* Length of ARG. */
|
||||
int matchind = -1; /* Index of first nonexact match. */
|
||||
int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */
|
||||
|
||||
arglen = strlen (arg);
|
||||
|
||||
/* Test all elements for either exact match or abbreviated matches. */
|
||||
for (i = 0; optlist[i]; i++)
|
||||
{
|
||||
if (!strncmp (optlist[i], arg, arglen))
|
||||
{
|
||||
if (strlen (optlist[i]) == arglen)
|
||||
/* Exact match found. */
|
||||
return i;
|
||||
else if (matchind == -1)
|
||||
/* First nonexact match found. */
|
||||
matchind = i;
|
||||
else
|
||||
/* Second nonexact match found. */
|
||||
ambiguous = 1;
|
||||
}
|
||||
}
|
||||
if (ambiguous)
|
||||
return -2;
|
||||
else
|
||||
return matchind;
|
||||
}
|
||||
|
||||
/* Error reporting for argmatch.
|
||||
KIND is a description of the type of entity that was being matched.
|
||||
VALUE is the invalid value that was given.
|
||||
PROBLEM is the return value from argmatch. */
|
||||
|
||||
void
|
||||
invalid_arg (kind, value, problem)
|
||||
char *kind;
|
||||
char *value;
|
||||
int problem;
|
||||
{
|
||||
fprintf (stderr, "patch: ");
|
||||
if (problem == -1)
|
||||
fprintf (stderr, "invalid");
|
||||
else /* Assume -2. */
|
||||
fprintf (stderr, "ambiguous");
|
||||
fprintf (stderr, " %s `%s'\n", kind, value);
|
||||
}
|
||||
|
||||
static char *backup_args[] =
|
||||
{
|
||||
"never", "simple", "nil", "existing", "t", "numbered", 0
|
||||
};
|
||||
|
||||
static enum backup_type backup_types[] =
|
||||
{
|
||||
simple, simple, numbered_existing, numbered_existing, numbered, numbered
|
||||
};
|
||||
|
||||
/* Return the type of backup indicated by VERSION.
|
||||
Unique abbreviations are accepted. */
|
||||
|
||||
enum backup_type
|
||||
get_version (version)
|
||||
char *version;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (version == 0 || *version == 0)
|
||||
return numbered_existing;
|
||||
i = argmatch (version, backup_args);
|
||||
if (i >= 0)
|
||||
return backup_types[i];
|
||||
invalid_arg ("version control type", version, i);
|
||||
exit (1);
|
||||
}
|
||||
#endif /* NODIR */
|
||||
|
||||
/* Append to FILENAME the extension EXT, unless the result would be too long,
|
||||
in which case just append the character E. */
|
||||
|
||||
void
|
||||
addext (filename, ext, e)
|
||||
char *filename, *ext;
|
||||
int e;
|
||||
{
|
||||
char *s = basename (filename);
|
||||
int slen = strlen (s), extlen = strlen (ext);
|
||||
long slen_max = -1;
|
||||
|
||||
#if HAVE_PATHCONF && defined (_PC_NAME_MAX)
|
||||
#ifndef _POSIX_NAME_MAX
|
||||
#define _POSIX_NAME_MAX 14
|
||||
#endif
|
||||
if (slen + extlen <= _POSIX_NAME_MAX)
|
||||
/* The file name is so short there's no need to call pathconf. */
|
||||
slen_max = _POSIX_NAME_MAX;
|
||||
else if (s == filename)
|
||||
slen_max = pathconf (".", _PC_NAME_MAX);
|
||||
else
|
||||
{
|
||||
char c = *s;
|
||||
*s = 0;
|
||||
slen_max = pathconf (filename, _PC_NAME_MAX);
|
||||
*s = c;
|
||||
}
|
||||
#endif
|
||||
if (slen_max == -1) {
|
||||
#ifdef HAVE_LONG_FILE_NAMES
|
||||
slen_max = 255;
|
||||
#else
|
||||
slen_max = 14;
|
||||
#endif
|
||||
}
|
||||
if (slen + extlen <= slen_max)
|
||||
strcpy (s + slen, ext);
|
||||
else
|
||||
{
|
||||
if (slen_max <= slen) {
|
||||
/* Try to preserve difference between .h .c etc. */
|
||||
if (slen == slen_max && s[slen - 2] == '.')
|
||||
s[slen - 2] = s[slen - 1];
|
||||
|
||||
slen = slen_max - 1;
|
||||
}
|
||||
s[slen] = e;
|
||||
s[slen + 1] = 0;
|
||||
}
|
||||
}
|
46
gnu/usr.bin/patch/backupfile.h
Normal file
46
gnu/usr.bin/patch/backupfile.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* backupfile.h -- declarations for making Emacs style backup file names
|
||||
Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* When to make backup files. */
|
||||
enum backup_type
|
||||
{
|
||||
/* Never make backups. */
|
||||
none,
|
||||
|
||||
/* Make simple backups of every file. */
|
||||
simple,
|
||||
|
||||
/* Make numbered backups of files that already have numbered backups,
|
||||
and simple backups of the others. */
|
||||
numbered_existing,
|
||||
|
||||
/* Make numbered backups of every file. */
|
||||
numbered
|
||||
};
|
||||
|
||||
extern enum backup_type backup_type;
|
||||
extern char *simple_backup_suffix;
|
||||
|
||||
#ifdef __STDC__
|
||||
char *find_backup_file_name (char *file);
|
||||
enum backup_type get_version (char *version);
|
||||
void addext (char *, char *, int);
|
||||
#else
|
||||
char *find_backup_file_name ();
|
||||
enum backup_type get_version ();
|
||||
void addext ();
|
||||
#endif
|
200
gnu/usr.bin/patch/common.h
Normal file
200
gnu/usr.bin/patch/common.h
Normal file
@ -0,0 +1,200 @@
|
||||
/* $Header: /home/ncvs/src/gnu/usr.bin/patch/common.h,v 1.3 1995/05/30 05:02:30 rgrimes Exp $
|
||||
*
|
||||
* $Log: common.h,v $
|
||||
* Revision 1.3 1995/05/30 05:02:30 rgrimes
|
||||
* Remove trailing whitespace.
|
||||
*
|
||||
* Revision 1.2 1993/09/22 16:51:03 rich
|
||||
* Increaed the fixed static buffer sizes and maximum hunk size that
|
||||
* otherwise causes the XFree86 1.3 patch set to fail.
|
||||
*
|
||||
* Revision 1.1.1.1 1993/06/19 14:21:52 paul
|
||||
* b-maked patch-2.10
|
||||
*
|
||||
* Revision 2.0.1.2 88/06/22 20:44:53 lwall
|
||||
* patch12: sprintf was declared wrong
|
||||
*
|
||||
* Revision 2.0.1.1 88/06/03 15:01:56 lwall
|
||||
* patch10: support for shorter extensions.
|
||||
*
|
||||
* Revision 2.0 86/09/17 15:36:39 lwall
|
||||
* Baseline for netwide release.
|
||||
*
|
||||
*/
|
||||
|
||||
#define DEBUGGING
|
||||
|
||||
#define VOIDUSED 7
|
||||
#include "config.h"
|
||||
|
||||
/* shut lint up about the following when return value ignored */
|
||||
|
||||
#define Signal (void)signal
|
||||
#define Unlink (void)unlink
|
||||
#define Lseek (void)lseek
|
||||
#define Fseek (void)fseek
|
||||
#define Fstat (void)fstat
|
||||
#define Pclose (void)pclose
|
||||
#define Close (void)close
|
||||
#define Fclose (void)fclose
|
||||
#define Fflush (void)fflush
|
||||
#define Sprintf (void)sprintf
|
||||
#define Mktemp (void)mktemp
|
||||
#define Strcpy (void)strcpy
|
||||
#define Strcat (void)strcat
|
||||
|
||||
/* NeXT declares malloc and realloc incompatibly from us in some of
|
||||
these files. Temporarily redefine them to prevent errors. */
|
||||
#define malloc system_malloc
|
||||
#define realloc system_realloc
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#undef malloc
|
||||
#undef realloc
|
||||
|
||||
/* constants */
|
||||
|
||||
/* AIX predefines these. */
|
||||
#ifdef TRUE
|
||||
#undef TRUE
|
||||
#endif
|
||||
#ifdef FALSE
|
||||
#undef FALSE
|
||||
#endif
|
||||
#define TRUE (1)
|
||||
#define FALSE (0)
|
||||
|
||||
#define MAXHUNKSIZE 200000 /* is this enough lines? */
|
||||
#define INITHUNKMAX 125 /* initial dynamic allocation size */
|
||||
#define MAXLINELEN 4096
|
||||
#define BUFFERSIZE 4096
|
||||
|
||||
#define SCCSPREFIX "s."
|
||||
#define GET "get %s"
|
||||
#define GET_LOCKED "get -e %s"
|
||||
#define SCCSDIFF "get -p %s | diff - %s >/dev/null"
|
||||
|
||||
#define RCSSUFFIX ",v"
|
||||
#define CHECKOUT "co %s"
|
||||
#define CHECKOUT_LOCKED "co -l %s"
|
||||
#define RCSDIFF "rcsdiff %s > /dev/null"
|
||||
|
||||
/* handy definitions */
|
||||
|
||||
#define Null(t) ((t)0)
|
||||
#define Nullch Null(char *)
|
||||
#define Nullfp Null(FILE *)
|
||||
#define Nulline Null(LINENUM)
|
||||
|
||||
#define Ctl(ch) ((ch) & 037)
|
||||
|
||||
#define strNE(s1,s2) (strcmp(s1, s2))
|
||||
#define strEQ(s1,s2) (!strcmp(s1, s2))
|
||||
#define strnNE(s1,s2,l) (strncmp(s1, s2, l))
|
||||
#define strnEQ(s1,s2,l) (!strncmp(s1, s2, l))
|
||||
|
||||
/* typedefs */
|
||||
|
||||
typedef char bool;
|
||||
typedef long LINENUM; /* must be signed */
|
||||
typedef unsigned MEM; /* what to feed malloc */
|
||||
|
||||
/* globals */
|
||||
|
||||
EXT int Argc; /* guess */
|
||||
EXT char **Argv;
|
||||
EXT int optind_last; /* for restarting plan_b */
|
||||
|
||||
EXT struct stat filestat; /* file statistics area */
|
||||
EXT int filemode INIT(0644);
|
||||
|
||||
EXT char buf[MAXLINELEN]; /* general purpose buffer */
|
||||
EXT FILE *ofp INIT(Nullfp); /* output file pointer */
|
||||
EXT FILE *rejfp INIT(Nullfp); /* reject file pointer */
|
||||
|
||||
EXT int myuid; /* cache getuid return value */
|
||||
|
||||
EXT bool using_plan_a INIT(TRUE); /* try to keep everything in memory */
|
||||
EXT bool out_of_mem INIT(FALSE); /* ran out of memory in plan a */
|
||||
|
||||
#define MAXFILEC 2
|
||||
EXT int filec INIT(0); /* how many file arguments? */
|
||||
EXT char *filearg[MAXFILEC];
|
||||
EXT bool ok_to_create_file INIT(FALSE);
|
||||
EXT char *bestguess INIT(Nullch); /* guess at correct filename */
|
||||
|
||||
EXT char *outname INIT(Nullch);
|
||||
EXT char rejname[128];
|
||||
|
||||
EXT char *origprae INIT(Nullch);
|
||||
|
||||
EXT char *TMPOUTNAME;
|
||||
EXT char *TMPINNAME;
|
||||
EXT char *TMPREJNAME;
|
||||
EXT char *TMPPATNAME;
|
||||
EXT bool toutkeep INIT(FALSE);
|
||||
EXT bool trejkeep INIT(FALSE);
|
||||
|
||||
EXT LINENUM last_offset INIT(0);
|
||||
#ifdef DEBUGGING
|
||||
EXT int debug INIT(0);
|
||||
#endif
|
||||
EXT LINENUM maxfuzz INIT(2);
|
||||
EXT bool force INIT(FALSE);
|
||||
EXT bool batch INIT(FALSE);
|
||||
EXT bool verbose INIT(TRUE);
|
||||
EXT bool reverse INIT(FALSE);
|
||||
EXT bool noreverse INIT(FALSE);
|
||||
EXT bool skip_rest_of_patch INIT(FALSE);
|
||||
EXT int strippath INIT(957);
|
||||
EXT bool canonicalize INIT(FALSE);
|
||||
|
||||
#define CONTEXT_DIFF 1
|
||||
#define NORMAL_DIFF 2
|
||||
#define ED_DIFF 3
|
||||
#define NEW_CONTEXT_DIFF 4
|
||||
#define UNI_DIFF 5
|
||||
EXT int diff_type INIT(0);
|
||||
|
||||
EXT bool do_defines INIT(FALSE); /* patch using ifdef, ifndef, etc. */
|
||||
EXT char if_defined[128]; /* #ifdef xyzzy */
|
||||
EXT char not_defined[128]; /* #ifndef xyzzy */
|
||||
EXT char else_defined[] INIT("#else\n");/* #else */
|
||||
EXT char end_defined[128]; /* #endif xyzzy */
|
||||
|
||||
EXT char *revision INIT(Nullch); /* prerequisite revision, if any */
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#else
|
||||
extern int errno;
|
||||
FILE *popen();
|
||||
char *malloc();
|
||||
char *realloc();
|
||||
long atol();
|
||||
char *getenv();
|
||||
char *strcpy();
|
||||
char *strcat();
|
||||
#endif
|
||||
char *mktemp();
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#else
|
||||
long lseek();
|
||||
#endif
|
||||
#if defined(_POSIX_VERSION) || defined(HAVE_FCNTL_H)
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if !defined(S_ISDIR) && defined(S_IFDIR)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#if !defined(S_ISREG) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
@ -1,125 +1,81 @@
|
||||
/* config.h. Generated automatically by configure. */
|
||||
/* config.hin. Generated automatically from configure.in by autoheader. */
|
||||
/* Portability variables. -*- C -*- */
|
||||
|
||||
/* 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. */
|
||||
/* Define if the system does not support the `const' keyword. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
/* Define if the system supports file names longer than 14 characters. */
|
||||
#define HAVE_LONG_FILE_NAMES
|
||||
|
||||
/* Define if you support file names longer than 14 characters. */
|
||||
#define HAVE_LONG_FILE_NAMES 1
|
||||
/* Define if the system has pathconf(). */
|
||||
/* #undef HAVE_PATHCONF */
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
/* Define if the system has strerror(). */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
/* Define if the system has ANSI C header files and library functions. */
|
||||
#define STDC_HEADERS
|
||||
|
||||
/* 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). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define if there is a member named d_ino in the struct describing
|
||||
directory headers. */
|
||||
#define D_INO_IN_DIRENT 1
|
||||
|
||||
/* Define if memchr works. */
|
||||
#define HAVE_MEMCHR 1
|
||||
|
||||
/* Define if `struct utimbuf' is declared -- usually in <utime.h>. */
|
||||
#define HAVE_STRUCT_UTIMBUF 1
|
||||
|
||||
/* Define if you have the _doprintf function. */
|
||||
/* #undef HAVE__DOPRINTF */
|
||||
|
||||
/* Define if you have the isascii function. */
|
||||
#define HAVE_ISASCII 1
|
||||
|
||||
/* Define if you have the memchr function. */
|
||||
#define HAVE_MEMCHR 1
|
||||
|
||||
/* Define if you have the memcmp function. */
|
||||
#define HAVE_MEMCMP 1
|
||||
|
||||
/* Define if you have the mkdir function. */
|
||||
#define HAVE_MKDIR 1
|
||||
|
||||
/* 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 raise function. */
|
||||
#define HAVE_RAISE 1
|
||||
|
||||
/* Define if you have the rename function. */
|
||||
#define HAVE_RENAME 1
|
||||
|
||||
/* Define if you have the sigaction function. */
|
||||
#define HAVE_SIGACTION 1
|
||||
|
||||
/* Define if you have the sigprocmask function. */
|
||||
#define HAVE_SIGPROCMASK 1
|
||||
|
||||
/* Define if you have the sigsetmask function. */
|
||||
#define HAVE_SIGSETMASK 1
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
/* Define if the system uses strchr instead of index
|
||||
and strrchr instead of rindex. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#endif
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
/* Define if the system has unistd.h. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define if you have the <utime.h> header file. */
|
||||
#define HAVE_UTIME_H 1
|
||||
/* Define if the system has fcntl.h. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define if you have the <varargs.h> header file. */
|
||||
#define HAVE_VARARGS_H 1
|
||||
/* Define as either int or void -- the type that signal handlers return. */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
#ifndef RETSIGTYPE
|
||||
#define RETSIGTYPE void
|
||||
#endif
|
||||
|
||||
/* Which directory library header to use. */
|
||||
#define DIRENT 1 /* dirent.h */
|
||||
/* #undef SYSNDIR */ /* sys/ndir.h */
|
||||
/* #undef SYSDIR */ /* sys/dir.h */
|
||||
/* #undef NDIR */ /* ndir.h */
|
||||
/* #undef NODIR */ /* none -- don't make numbered backup files */
|
||||
|
||||
/* Define if the system lets you pass fewer arguments to a function
|
||||
than the function actually accepts (in the absence of a prototype).
|
||||
Defining it makes I/O calls slightly more efficient.
|
||||
You need not bother defining it unless your C preprocessor chokes on
|
||||
multi-line arguments to macros. */
|
||||
/* #undef CANVARARG */
|
||||
|
||||
/* Define Reg* as either `register' or nothing, depending on whether
|
||||
the C compiler pays attention to this many register declarations.
|
||||
The intent is that you don't have to order your register declarations
|
||||
in the order of importance, so you can freely declare register variables
|
||||
in sub-blocks of code and as function parameters.
|
||||
Do not use Reg<n> more than once per routine.
|
||||
|
||||
These don't really matter a lot, since most modern C compilers ignore
|
||||
register declarations and often do a better job of allocating
|
||||
registers than people do. */
|
||||
|
||||
#define Reg1 register
|
||||
#define Reg2 register
|
||||
#define Reg3 register
|
||||
#define Reg4 register
|
||||
#define Reg5 register
|
||||
#define Reg6 register
|
||||
#define Reg7
|
||||
#define Reg8
|
||||
#define Reg9
|
||||
#define Reg10
|
||||
#define Reg11
|
||||
#define Reg12
|
||||
#define Reg13
|
||||
#define Reg14
|
||||
#define Reg15
|
||||
#define Reg16
|
||||
|
732
gnu/usr.bin/patch/getopt.c
Normal file
732
gnu/usr.bin/patch/getopt.c
Normal file
@ -0,0 +1,732 @@
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* NOTE!!! AIX requires this to be the first thing in the file.
|
||||
Do not put ANYTHING before it! */
|
||||
#if !defined (__GNUC__) && defined (_AIX)
|
||||
#pragma alloca
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else /* not __GNUC__ */
|
||||
#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#ifndef _AIX
|
||||
char *alloca ();
|
||||
#endif
|
||||
#endif /* alloca.h */
|
||||
#endif /* not __GNUC__ */
|
||||
|
||||
#if !__STDC__ && !defined(const) && IN_GCC
|
||||
#define const
|
||||
#endif
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#undef alloca
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#else /* Not GNU C library. */
|
||||
#define __alloca alloca
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
|
||||
long-named option. Because this is not POSIX.2 compliant, it is
|
||||
being phased out. */
|
||||
/* #define GETOPT_COMPAT */
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of ARGV so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = 0;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
int optopt = '?';
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n))
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
char *getenv ();
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
const char *str;
|
||||
int chr;
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
my_bcopy (from, to, size)
|
||||
const char *from;
|
||||
char *to;
|
||||
int size;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
to[i] = from[i];
|
||||
}
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
|
||||
char **temp = (char **) __alloca (nonopts_size);
|
||||
|
||||
/* Interchange the two blocks of data in ARGV. */
|
||||
|
||||
my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
|
||||
my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
|
||||
(optind - last_nonopt) * sizeof (char *));
|
||||
my_bcopy ((char *) temp,
|
||||
(char *) &argv[first_nonopt + optind - last_nonopt],
|
||||
nonopts_size);
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with `--' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||
`flag' field is nonzero, the value of the option's `val' field
|
||||
if the `flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
const struct option *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
int option_index;
|
||||
|
||||
optarg = 0;
|
||||
|
||||
/* Initialize the internal data when the first call is made.
|
||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
if (optind == 0)
|
||||
{
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (getenv ("POSIXLY_CORRECT") != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
}
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Now skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Start decoding its characters. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
if (longopts != NULL
|
||||
&& ((argv[optind][0] == '-'
|
||||
&& (argv[optind][1] == '-' || long_only))
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
))
|
||||
{
|
||||
const struct option *p;
|
||||
char *s = nextchar;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
const struct option *pfound = NULL;
|
||||
int indfound;
|
||||
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
|
||||
/* Test all options for either exact match or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name;
|
||||
p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, s - nextchar))
|
||||
{
|
||||
if (s - nextchar == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*s)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = s + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
"%s: option `--%s' doesn't allow an argument\n",
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
"%s: option `%c%s' doesn't allow an argument\n",
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
if (c < 040 || c >= 0177)
|
||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = 0;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||
argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
129
gnu/usr.bin/patch/getopt.h
Normal file
129
gnu/usr.bin/patch/getopt.h
Normal file
@ -0,0 +1,129 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if __STDC__
|
||||
#if defined(__GNU_LIBRARY__)
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* not __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
176
gnu/usr.bin/patch/getopt1.c
Normal file
176
gnu/usr.bin/patch/getopt1.c
Normal file
@ -0,0 +1,176 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !__STDC__ && !defined(const) && IN_GCC
|
||||
#define const
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *getenv ();
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
410
gnu/usr.bin/patch/inp.c
Normal file
410
gnu/usr.bin/patch/inp.c
Normal file
@ -0,0 +1,410 @@
|
||||
/* $Header: /home/ncvs/src/gnu/usr.bin/patch/inp.c,v 1.6 1997/10/23 02:44:21 ache Exp $
|
||||
*
|
||||
* $Log: inp.c,v $
|
||||
* Revision 1.6 1997/10/23 02:44:21 ache
|
||||
* Add (unsigned char) cast to ctype macros
|
||||
*
|
||||
* Revision 1.5 1997/03/17 01:44:40 jmg
|
||||
* fix compilation warnings in patch... (with slight modification)
|
||||
*
|
||||
* also remove -Wall that I acidentally committed last time I was here...
|
||||
*
|
||||
* Submitted-by: Philippe Charnier
|
||||
*
|
||||
* Closes PR#2998
|
||||
*
|
||||
* Revision 1.4 1997/02/13 21:10:39 jmg
|
||||
* Fix a problem with patch in that is will always default, even when the
|
||||
* controlling terminal is closed. Now the function ask() will return 1 when th
|
||||
* input is known to come from a file or terminal, or it will return 0 when ther
|
||||
* was a read error.
|
||||
*
|
||||
* Modified the question "Skip patch?" so that on an error from ask it will skip
|
||||
* the patch instead of looping.
|
||||
*
|
||||
* Closes PR#777
|
||||
*
|
||||
* 2.2 candidate
|
||||
*
|
||||
* Revision 1.3 1995/05/30 05:02:31 rgrimes
|
||||
* Remove trailing whitespace.
|
||||
*
|
||||
* Revision 1.2 1995/01/12 22:09:39 hsu
|
||||
* Fix bug that created new files even when running in -C check mode.
|
||||
* Reviewed by: phk
|
||||
*
|
||||
* Revision 1.1.1.1 1993/06/19 14:21:52 paul
|
||||
* b-maked patch-2.10
|
||||
*
|
||||
* Revision 2.0.1.1 88/06/03 15:06:13 lwall
|
||||
* patch10: made a little smarter about sccs files
|
||||
*
|
||||
* Revision 2.0 86/09/17 15:37:02 lwall
|
||||
* Baseline for netwide release.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EXTERN.h"
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "pch.h"
|
||||
#include "INTERN.h"
|
||||
#include "inp.h"
|
||||
|
||||
/* Input-file-with-indexable-lines abstract type */
|
||||
|
||||
static long i_size; /* size of the input file */
|
||||
static char *i_womp; /* plan a buffer for entire file */
|
||||
static char **i_ptr; /* pointers to lines in i_womp */
|
||||
|
||||
static int tifd = -1; /* plan b virtual string array */
|
||||
static char *tibuf[2]; /* plan b buffers */
|
||||
static LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */
|
||||
static LINENUM lines_per_buf; /* how many lines per buffer */
|
||||
static int tireclen; /* length of records in tmp file */
|
||||
|
||||
/* New patch--prepare to edit another file. */
|
||||
|
||||
void
|
||||
re_input()
|
||||
{
|
||||
if (using_plan_a) {
|
||||
i_size = 0;
|
||||
#ifndef lint
|
||||
if (i_ptr != Null(char**))
|
||||
free((char *)i_ptr);
|
||||
#endif
|
||||
if (i_womp != Nullch)
|
||||
free(i_womp);
|
||||
i_womp = Nullch;
|
||||
i_ptr = Null(char **);
|
||||
}
|
||||
else {
|
||||
using_plan_a = TRUE; /* maybe the next one is smaller */
|
||||
Close(tifd);
|
||||
tifd = -1;
|
||||
free(tibuf[0]);
|
||||
free(tibuf[1]);
|
||||
tibuf[0] = tibuf[1] = Nullch;
|
||||
tiline[0] = tiline[1] = -1;
|
||||
tireclen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Constuct the line index, somehow or other. */
|
||||
|
||||
void
|
||||
scan_input(filename)
|
||||
char *filename;
|
||||
{
|
||||
if (!plan_a(filename))
|
||||
plan_b(filename);
|
||||
if (verbose) {
|
||||
say3("Patching file %s using Plan %s...\n", filename,
|
||||
(using_plan_a ? "A" : "B") );
|
||||
}
|
||||
}
|
||||
|
||||
/* Try keeping everything in memory. */
|
||||
|
||||
bool
|
||||
plan_a(filename)
|
||||
char *filename;
|
||||
{
|
||||
int ifd, statfailed;
|
||||
Reg1 char *s;
|
||||
Reg2 LINENUM iline;
|
||||
char lbuf[MAXLINELEN];
|
||||
int output_elsewhere = strcmp(filename, outname);
|
||||
extern int check_patch;
|
||||
|
||||
statfailed = stat(filename, &filestat);
|
||||
if (statfailed && ok_to_create_file) {
|
||||
if (verbose)
|
||||
say2("(Creating file %s...)\n",filename);
|
||||
if (check_patch)
|
||||
return TRUE;
|
||||
makedirs(filename, TRUE);
|
||||
close(creat(filename, 0666));
|
||||
statfailed = stat(filename, &filestat);
|
||||
}
|
||||
if (statfailed && check_patch) {
|
||||
fatal2("%s not found and in check_patch mode.", filename);
|
||||
}
|
||||
/* For nonexistent or read-only files, look for RCS or SCCS versions. */
|
||||
if (statfailed
|
||||
|| (! output_elsewhere
|
||||
&& (/* No one can write to it. */
|
||||
(filestat.st_mode & 0222) == 0
|
||||
/* I can't write to it. */
|
||||
|| ((filestat.st_mode & 0022) == 0
|
||||
&& filestat.st_uid != myuid)))) {
|
||||
struct stat cstat;
|
||||
char *cs = Nullch;
|
||||
char *filebase;
|
||||
int pathlen;
|
||||
|
||||
filebase = basename(filename);
|
||||
pathlen = filebase - filename;
|
||||
|
||||
/* Put any leading path into `s'.
|
||||
Leave room in lbuf for the diff command. */
|
||||
s = lbuf + 20;
|
||||
strncpy(s, filename, pathlen);
|
||||
|
||||
#define try(f,a1,a2) (Sprintf(s + pathlen, f, a1, a2), stat(s, &cstat) == 0)
|
||||
if (( try("RCS/%s%s", filebase, RCSSUFFIX)
|
||||
|| try("RCS/%s%s", filebase, "")
|
||||
|| try( "%s%s", filebase, RCSSUFFIX))
|
||||
&&
|
||||
/* Check that RCS file is not working file.
|
||||
Some hosts don't report file name length errors. */
|
||||
(statfailed
|
||||
|| ( (filestat.st_dev ^ cstat.st_dev)
|
||||
| (filestat.st_ino ^ cstat.st_ino)))) {
|
||||
Sprintf(buf, output_elsewhere?CHECKOUT:CHECKOUT_LOCKED, filename);
|
||||
Sprintf(lbuf, RCSDIFF, filename);
|
||||
cs = "RCS";
|
||||
} else if ( try("SCCS/%s%s", SCCSPREFIX, filebase)
|
||||
|| try( "%s%s", SCCSPREFIX, filebase)) {
|
||||
Sprintf(buf, output_elsewhere?GET:GET_LOCKED, s);
|
||||
Sprintf(lbuf, SCCSDIFF, s, filename);
|
||||
cs = "SCCS";
|
||||
} else if (statfailed)
|
||||
fatal2("can't find %s\n", filename);
|
||||
/* else we can't write to it but it's not under a version
|
||||
control system, so just proceed. */
|
||||
if (cs) {
|
||||
if (!statfailed) {
|
||||
if ((filestat.st_mode & 0222) != 0)
|
||||
/* The owner can write to it. */
|
||||
fatal3("file %s seems to be locked by somebody else under %s\n",
|
||||
filename, cs);
|
||||
/* It might be checked out unlocked. See if it's safe to
|
||||
check out the default version locked. */
|
||||
if (verbose)
|
||||
say3("Comparing file %s to default %s version...\n",
|
||||
filename, cs);
|
||||
if (system(lbuf))
|
||||
fatal3("can't check out file %s: differs from default %s version\n",
|
||||
filename, cs);
|
||||
}
|
||||
if (verbose)
|
||||
say3("Checking out file %s from %s...\n", filename, cs);
|
||||
if (system(buf) || stat(filename, &filestat))
|
||||
fatal3("can't check out file %s from %s\n", filename, cs);
|
||||
}
|
||||
}
|
||||
filemode = filestat.st_mode;
|
||||
if (!S_ISREG(filemode))
|
||||
fatal2("%s is not a normal file--can't patch\n", filename);
|
||||
i_size = filestat.st_size;
|
||||
if (out_of_mem) {
|
||||
set_hunkmax(); /* make sure dynamic arrays are allocated */
|
||||
out_of_mem = FALSE;
|
||||
return FALSE; /* force plan b because plan a bombed */
|
||||
}
|
||||
#ifdef lint
|
||||
i_womp = Nullch;
|
||||
#else
|
||||
i_womp = malloc((MEM)(i_size+2)); /* lint says this may alloc less than */
|
||||
/* i_size, but that's okay, I think. */
|
||||
#endif
|
||||
if (i_womp == Nullch)
|
||||
return FALSE;
|
||||
if ((ifd = open(filename, 0)) < 0)
|
||||
pfatal2("can't open file %s", filename);
|
||||
#ifndef lint
|
||||
if (read(ifd, i_womp, (int)i_size) != i_size) {
|
||||
Close(ifd); /* probably means i_size > 15 or 16 bits worth */
|
||||
free(i_womp); /* at this point it doesn't matter if i_womp was */
|
||||
return FALSE; /* undersized. */
|
||||
}
|
||||
#endif
|
||||
Close(ifd);
|
||||
if (i_size && i_womp[i_size-1] != '\n')
|
||||
i_womp[i_size++] = '\n';
|
||||
i_womp[i_size] = '\0';
|
||||
|
||||
/* count the lines in the buffer so we know how many pointers we need */
|
||||
|
||||
iline = 0;
|
||||
for (s=i_womp; *s; s++) {
|
||||
if (*s == '\n')
|
||||
iline++;
|
||||
}
|
||||
#ifdef lint
|
||||
i_ptr = Null(char**);
|
||||
#else
|
||||
i_ptr = (char **)malloc((MEM)((iline + 2) * sizeof(char *)));
|
||||
#endif
|
||||
if (i_ptr == Null(char **)) { /* shucks, it was a near thing */
|
||||
free((char *)i_womp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* now scan the buffer and build pointer array */
|
||||
|
||||
iline = 1;
|
||||
i_ptr[iline] = i_womp;
|
||||
for (s=i_womp; *s; s++) {
|
||||
if (*s == '\n')
|
||||
i_ptr[++iline] = s+1; /* these are NOT null terminated */
|
||||
}
|
||||
input_lines = iline - 1;
|
||||
|
||||
/* now check for revision, if any */
|
||||
|
||||
if (revision != Nullch) {
|
||||
if (!rev_in_string(i_womp)) {
|
||||
if (force) {
|
||||
if (verbose)
|
||||
say2(
|
||||
"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
|
||||
revision);
|
||||
}
|
||||
else if (batch) {
|
||||
fatal2(
|
||||
"this file doesn't appear to be the %s version--aborting.\n", revision);
|
||||
}
|
||||
else {
|
||||
(void) ask2(
|
||||
"This file doesn't appear to be the %s version--patch anyway? [n] ",
|
||||
revision);
|
||||
if (*buf != 'y')
|
||||
fatal1("aborted\n");
|
||||
}
|
||||
}
|
||||
else if (verbose)
|
||||
say2("Good. This file appears to be the %s version.\n",
|
||||
revision);
|
||||
}
|
||||
return TRUE; /* plan a will work */
|
||||
}
|
||||
|
||||
/* Keep (virtually) nothing in memory. */
|
||||
|
||||
void
|
||||
plan_b(filename)
|
||||
char *filename;
|
||||
{
|
||||
Reg3 FILE *ifp;
|
||||
Reg1 int i = 0;
|
||||
Reg2 int maxlen = 1;
|
||||
Reg4 bool found_revision = (revision == Nullch);
|
||||
|
||||
using_plan_a = FALSE;
|
||||
if ((ifp = fopen(filename, "r")) == Nullfp)
|
||||
pfatal2("can't open file %s", filename);
|
||||
if ((tifd = creat(TMPINNAME, 0666)) < 0)
|
||||
pfatal2("can't open file %s", TMPINNAME);
|
||||
while (fgets(buf, sizeof buf, ifp) != Nullch) {
|
||||
if (revision != Nullch && !found_revision && rev_in_string(buf))
|
||||
found_revision = TRUE;
|
||||
if ((i = strlen(buf)) > maxlen)
|
||||
maxlen = i; /* find longest line */
|
||||
}
|
||||
if (revision != Nullch) {
|
||||
if (!found_revision) {
|
||||
if (force) {
|
||||
if (verbose)
|
||||
say2(
|
||||
"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
|
||||
revision);
|
||||
}
|
||||
else if (batch) {
|
||||
fatal2(
|
||||
"this file doesn't appear to be the %s version--aborting.\n", revision);
|
||||
}
|
||||
else {
|
||||
(void) ask2(
|
||||
"This file doesn't appear to be the %s version--patch anyway? [n] ",
|
||||
revision);
|
||||
if (*buf != 'y')
|
||||
fatal1("aborted\n");
|
||||
}
|
||||
}
|
||||
else if (verbose)
|
||||
say2("Good. This file appears to be the %s version.\n",
|
||||
revision);
|
||||
}
|
||||
Fseek(ifp, 0L, 0); /* rewind file */
|
||||
lines_per_buf = BUFFERSIZE / maxlen;
|
||||
tireclen = maxlen;
|
||||
tibuf[0] = malloc((MEM)(BUFFERSIZE + 1));
|
||||
tibuf[1] = malloc((MEM)(BUFFERSIZE + 1));
|
||||
if (tibuf[1] == Nullch)
|
||||
fatal1("out of memory\n");
|
||||
for (i=1; ; i++) {
|
||||
if (! (i % lines_per_buf)) /* new block */
|
||||
if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
|
||||
pfatal1("can't write temp file");
|
||||
if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp)
|
||||
== Nullch) {
|
||||
input_lines = i - 1;
|
||||
if (i % lines_per_buf)
|
||||
if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
|
||||
pfatal1("can't write temp file");
|
||||
break;
|
||||
}
|
||||
}
|
||||
Fclose(ifp);
|
||||
Close(tifd);
|
||||
if ((tifd = open(TMPINNAME, 0)) < 0) {
|
||||
pfatal2("can't reopen file %s", TMPINNAME);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch a line from the input file, \n terminated, not necessarily \0. */
|
||||
|
||||
char *
|
||||
ifetch(line,whichbuf)
|
||||
Reg1 LINENUM line;
|
||||
int whichbuf; /* ignored when file in memory */
|
||||
{
|
||||
if (line < 1 || line > input_lines)
|
||||
return "";
|
||||
if (using_plan_a)
|
||||
return i_ptr[line];
|
||||
else {
|
||||
LINENUM offline = line % lines_per_buf;
|
||||
LINENUM baseline = line - offline;
|
||||
|
||||
if (tiline[0] == baseline)
|
||||
whichbuf = 0;
|
||||
else if (tiline[1] == baseline)
|
||||
whichbuf = 1;
|
||||
else {
|
||||
tiline[whichbuf] = baseline;
|
||||
#ifndef lint /* complains of long accuracy */
|
||||
Lseek(tifd, (long)baseline / lines_per_buf * BUFFERSIZE, 0);
|
||||
#endif
|
||||
if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
|
||||
pfatal2("error reading tmp file %s", TMPINNAME);
|
||||
}
|
||||
return tibuf[whichbuf] + (tireclen*offline);
|
||||
}
|
||||
}
|
||||
|
||||
/* True if the string argument contains the revision number we want. */
|
||||
|
||||
bool
|
||||
rev_in_string(string)
|
||||
char *string;
|
||||
{
|
||||
Reg1 char *s;
|
||||
Reg2 int patlen;
|
||||
|
||||
if (revision == Nullch)
|
||||
return TRUE;
|
||||
patlen = strlen(revision);
|
||||
if (strnEQ(string,revision,patlen) && isspace((unsigned char)string[patlen]))
|
||||
return TRUE;
|
||||
for (s = string; *s; s++) {
|
||||
if (isspace((unsigned char)*s) && strnEQ(s+1, revision, patlen) &&
|
||||
isspace((unsigned char)s[patlen+1] )) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
24
gnu/usr.bin/patch/inp.h
Normal file
24
gnu/usr.bin/patch/inp.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* $Header: /home/ncvs/src/gnu/usr.bin/patch/inp.h,v 1.2 1995/05/30 05:02:33 rgrimes Exp $
|
||||
*
|
||||
* $Log: inp.h,v $
|
||||
* Revision 1.2 1995/05/30 05:02:33 rgrimes
|
||||
* Remove trailing whitespace.
|
||||
*
|
||||
* Revision 1.1.1.1 1993/06/19 14:21:52 paul
|
||||
* b-maked patch-2.10
|
||||
*
|
||||
* Revision 2.0 86/09/17 15:37:25 lwall
|
||||
* Baseline for netwide release.
|
||||
*
|
||||
*/
|
||||
|
||||
EXT LINENUM input_lines INIT(0); /* how long is input file in lines */
|
||||
EXT LINENUM last_frozen_line INIT(0); /* how many input lines have been */
|
||||
/* irretractibly output */
|
||||
|
||||
bool rev_in_string();
|
||||
void scan_input();
|
||||
bool plan_a(); /* returns false if insufficient memory */
|
||||
void plan_b();
|
||||
char *ifetch();
|
||||
|
590
gnu/usr.bin/patch/patch.1
Normal file
590
gnu/usr.bin/patch/patch.1
Normal file
@ -0,0 +1,590 @@
|
||||
.\" -*- nroff -*-
|
||||
.rn '' }`
|
||||
'\" $Header: /home/ncvs/src/gnu/usr.bin/patch/Attic/patch.1,v 1.5.2.1 1998/01/11 20:45:30 ache Exp $
|
||||
'\"
|
||||
'\" $Log: patch.1,v $
|
||||
'\" Revision 1.5.2.1 1998/01/11 20:45:30 ache
|
||||
'\" Back out rev1.5 change, Index: precedence restored to historycal behaviour
|
||||
'\"
|
||||
'\" Revision 1.4 1994/02/25 21:45:59 phk
|
||||
'\" added the -C/-check again.
|
||||
'\"
|
||||
.\" Revision 1.3 1994/02/17 22:20:33 jkh
|
||||
.\" Put this back - I was somehow under the erroneous impression that patch was in
|
||||
.\" ports, until I saw the the commit messages, that is! :-) All changed backed out.
|
||||
.\"
|
||||
.\" Revision 1.2 1994/02/17 22:16:02 jkh
|
||||
.\" From Poul-Henning Kamp - Implement a -C option to verify the integrity of
|
||||
.\" a patch before actually applying it.
|
||||
.\"
|
||||
.\" Revision 1.1.1.1 1993/06/19 14:21:51 paul
|
||||
.\" b-maked patch-2.10
|
||||
.\"
|
||||
'\" Revision 2.0.1.2 88/06/22 20:47:18 lwall
|
||||
'\" patch12: now avoids Bell System Logo
|
||||
'\"
|
||||
'\" Revision 2.0.1.1 88/06/03 15:12:51 lwall
|
||||
'\" patch10: -B switch was contributed.
|
||||
'\"
|
||||
'\" Revision 2.0 86/09/17 15:39:09 lwall
|
||||
'\" Baseline for netwide release.
|
||||
'\"
|
||||
'\" Revision 1.4 86/08/01 19:23:22 lwall
|
||||
'\" Documented -v, -p, -F.
|
||||
'\" Added notes to patch senders.
|
||||
'\"
|
||||
'\" Revision 1.3 85/03/26 15:11:06 lwall
|
||||
'\" Frozen.
|
||||
'\"
|
||||
'\" Revision 1.2.1.4 85/03/12 16:14:27 lwall
|
||||
'\" Documented -p.
|
||||
'\"
|
||||
'\" Revision 1.2.1.3 85/03/12 16:09:41 lwall
|
||||
'\" Documented -D.
|
||||
'\"
|
||||
'\" Revision 1.2.1.2 84/12/05 11:06:55 lwall
|
||||
'\" Added -l switch, and noted bistability bug.
|
||||
'\"
|
||||
'\" Revision 1.2.1.1 84/12/04 17:23:39 lwall
|
||||
'\" Branch for sdcrdcf changes.
|
||||
'\"
|
||||
'\" Revision 1.2 84/12/04 17:22:02 lwall
|
||||
'\" Baseline version.
|
||||
'\"
|
||||
.de Sh
|
||||
.br
|
||||
.ne 5
|
||||
.PP
|
||||
\fB\\$1\fR
|
||||
.PP
|
||||
..
|
||||
.de Sp
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
'\"
|
||||
'\" Set up \*(-- to give an unbreakable dash;
|
||||
'\" string Tr holds user defined translation string.
|
||||
'\" Bell System Logo is used as a dummy character.
|
||||
'\"
|
||||
.ie n \{\
|
||||
.tr \(*W-\*(Tr
|
||||
.ds -- \(*W-
|
||||
.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||
.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||
.ds L" ""
|
||||
.ds R" ""
|
||||
.ds L' '
|
||||
.ds R' '
|
||||
'br \}
|
||||
.el \{\
|
||||
.ds -- \(em\|
|
||||
.tr \*(Tr
|
||||
.ds L" ``
|
||||
.ds R" ''
|
||||
.ds L' `
|
||||
.ds R' '
|
||||
'br\}
|
||||
.TH PATCH 1 LOCAL
|
||||
.SH NAME
|
||||
patch - apply a diff file to an original
|
||||
.SH SYNOPSIS
|
||||
.B patch
|
||||
[options] [origfile [patchfile]] [+ [options] [origfile]]...
|
||||
.sp
|
||||
but usually just
|
||||
.sp
|
||||
.B patch
|
||||
<patchfile
|
||||
.SH DESCRIPTION
|
||||
.I Patch
|
||||
will take a patch file containing any of the four forms of difference
|
||||
listing produced by the
|
||||
.I diff
|
||||
program and apply those differences to an original file, producing a patched
|
||||
version.
|
||||
By default, the patched version is put in place of the original, with
|
||||
the original file backed up to the same name with the
|
||||
extension \*(L".orig\*(R" (\*(L"~\*(R" on systems that do not
|
||||
support long file names), or as specified by the
|
||||
\fB\-b\fP (\fB\-\-suffix\fP),
|
||||
\fB\-B\fP (\fB\-\-prefix\fP),
|
||||
or
|
||||
\fB\-V\fP (\fB\-\-version\-control\fP)
|
||||
options.
|
||||
The extension used for making backup files may also be specified in the
|
||||
.B SIMPLE_BACKUP_SUFFIX
|
||||
environment variable, which is overridden by the above options.
|
||||
.PP
|
||||
If the backup file already exists,
|
||||
.B patch
|
||||
creates a new backup file name by changing the first lowercase letter
|
||||
in the last component of the file's name into uppercase. If there are
|
||||
no more lowercase letters in the name, it removes the first character
|
||||
from the name. It repeats this process until it comes up with a
|
||||
backup file that does not already exist.
|
||||
.PP
|
||||
You may also specify where you want the output to go with a
|
||||
\fB\-o\fP (\fB\-\-output\fP)
|
||||
option; if that file already exists, it is backed up first.
|
||||
.PP
|
||||
If
|
||||
.I patchfile
|
||||
is omitted, or is a hyphen, the patch will be read from standard input.
|
||||
.PP
|
||||
Upon startup, patch will attempt to determine the type of the diff listing,
|
||||
unless over-ruled by a
|
||||
\fB\-c\fP (\fB\-\-context\fP),
|
||||
\fB\-e\fP (\fB\-\-ed\fP),
|
||||
\fB\-n\fP (\fB\-\-normal\fP),
|
||||
or
|
||||
\fB\-u\fP (\fB\-\-unified\fP)
|
||||
option.
|
||||
Context diffs (old-style, new-style, and unified) and
|
||||
normal diffs are applied by the
|
||||
.I patch
|
||||
program itself, while
|
||||
.I ed
|
||||
diffs are simply fed to the
|
||||
.I ed
|
||||
editor via a pipe.
|
||||
.PP
|
||||
.I Patch
|
||||
will try to skip any leading garbage, apply the diff,
|
||||
and then skip any trailing garbage.
|
||||
Thus you could feed an article or message containing a
|
||||
diff listing to
|
||||
.IR patch ,
|
||||
and it should work.
|
||||
If the entire diff is indented by a consistent amount,
|
||||
this will be taken into account.
|
||||
.PP
|
||||
With context diffs, and to a lesser extent with normal diffs,
|
||||
.I patch
|
||||
can detect when the line numbers mentioned in the patch are incorrect,
|
||||
and will attempt to find the correct place to apply each hunk of the patch.
|
||||
As a first guess, it takes the line number mentioned for the hunk, plus or
|
||||
minus any offset used in applying the previous hunk.
|
||||
If that is not the correct place,
|
||||
.I patch
|
||||
will scan both forwards and backwards for a set of lines matching the context
|
||||
given in the hunk.
|
||||
First
|
||||
.I patch
|
||||
looks for a place where all lines of the context match.
|
||||
If no such place is found, and it's a context diff, and the maximum fuzz factor
|
||||
is set to 1 or more, then another scan takes place ignoring the first and last
|
||||
line of context.
|
||||
If that fails, and the maximum fuzz factor is set to 2 or more,
|
||||
the first two and last two lines of context are ignored,
|
||||
and another scan is made.
|
||||
(The default maximum fuzz factor is 2.)
|
||||
If
|
||||
.I patch
|
||||
cannot find a place to install that hunk of the patch, it will put the
|
||||
hunk out to a reject file, which normally is the name of the output file
|
||||
plus \*(L".rej\*(R" (\*(L"#\*(R" on systems that do not support
|
||||
long file names).
|
||||
(Note that the rejected hunk will come out in context diff form whether the
|
||||
input patch was a context diff or a normal diff.
|
||||
If the input was a normal diff, many of the contexts will simply be null.)
|
||||
The line numbers on the hunks in the reject file may be different than
|
||||
in the patch file: they reflect the approximate location patch thinks the
|
||||
failed hunks belong in the new file rather than the old one.
|
||||
.PP
|
||||
As each hunk is completed, you will be told whether the hunk succeeded or
|
||||
failed, and which line (in the new file)
|
||||
.I patch
|
||||
thought the hunk should go on.
|
||||
If this is different from the line number specified in the diff you will
|
||||
be told the offset.
|
||||
A single large offset MAY be an indication that a hunk was installed in the
|
||||
wrong place.
|
||||
You will also be told if a fuzz factor was used to make the match, in which
|
||||
case you should also be slightly suspicious.
|
||||
.PP
|
||||
If no original file is specified on the command line,
|
||||
.I patch
|
||||
will try to figure out from the leading garbage what the name of the file
|
||||
to edit is.
|
||||
In the header of a context diff, the file name is found from lines beginning
|
||||
with \*(L"***\*(R" or \*(L"---\*(R", with the shortest name of an existing
|
||||
file winning.
|
||||
Only context diffs have lines like that, but if there is an \*(L"Index:\*(R"
|
||||
line in the leading garbage,
|
||||
.I patch
|
||||
will try to use the file name from that line.
|
||||
The context diff header takes precedence over an Index line.
|
||||
If no file name can be intuited from the leading garbage, you will be asked
|
||||
for the name of the file to patch.
|
||||
.PP
|
||||
If the original file cannot be found or is read-only, but a suitable
|
||||
SCCS or RCS file is handy,
|
||||
.I patch
|
||||
will attempt to get or check out the file.
|
||||
.PP
|
||||
Additionally, if the leading garbage contains a \*(L"Prereq: \*(R" line,
|
||||
.I patch
|
||||
will take the first word from the prerequisites line (normally a version
|
||||
number) and check the input file to see if that word can be found.
|
||||
If not,
|
||||
.I patch
|
||||
will ask for confirmation before proceeding.
|
||||
.PP
|
||||
The upshot of all this is that you should be able to say, while in a news
|
||||
interface, the following:
|
||||
.Sp
|
||||
| patch -d /usr/src/local/blurfl
|
||||
.Sp
|
||||
and patch a file in the blurfl directory directly from the article containing
|
||||
the patch.
|
||||
.PP
|
||||
If the patch file contains more than one patch,
|
||||
.I patch
|
||||
will try to apply each of them as if they came from separate patch files.
|
||||
This means, among other things, that it is assumed that the name of the file
|
||||
to patch must be determined for each diff listing,
|
||||
and that the garbage before each diff listing will
|
||||
be examined for interesting things such as file names and revision level, as
|
||||
mentioned previously.
|
||||
You can give options (and another original file name) for the second and
|
||||
subsequent patches by separating the corresponding argument lists
|
||||
by a \*(L'+\*(R'.
|
||||
(The argument list for a second or subsequent patch may not specify a new
|
||||
patch file, however.)
|
||||
.PP
|
||||
.I Patch
|
||||
recognizes the following options:
|
||||
.TP 5
|
||||
.B "\-b suff, \-\-suffix=suff"
|
||||
causes
|
||||
.B suff
|
||||
to be interpreted as the backup extension, to be
|
||||
used in place of \*(L".orig\*(R" or \*(L"~\*(R".
|
||||
.TP 5
|
||||
.B "\-B pref, \-\-prefix=pref"
|
||||
causes
|
||||
.B pref
|
||||
to be interpreted as a prefix to the backup file
|
||||
name. If this argument is specified, any argument from
|
||||
.B \-b
|
||||
will be ignored.
|
||||
.TP 5
|
||||
.B "\-c, \-\-context"
|
||||
forces
|
||||
.I patch
|
||||
to interpret the patch file as a context diff.
|
||||
.TP 5
|
||||
.B "\-C, \-\-check"
|
||||
see what would happen, but don't do it.
|
||||
.TP 5
|
||||
.B "\-d dir, \-\-directory=dir"
|
||||
causes
|
||||
.I patch
|
||||
to interpret
|
||||
.B dir
|
||||
as a directory, and cd to it before doing
|
||||
anything else.
|
||||
.TP 5
|
||||
.B "\-D sym, \-\-ifdef=sym"
|
||||
causes
|
||||
.I patch
|
||||
to use the "#ifdef...#endif" construct to mark changes.
|
||||
.B sym
|
||||
will be used as the differentiating symbol.
|
||||
.TP 5
|
||||
.B "\-e, \-\-ed"
|
||||
forces
|
||||
.I patch
|
||||
to interpret the patch file as an
|
||||
.I ed
|
||||
script.
|
||||
.TP 5
|
||||
.B "\-E, \-\-remove\-empty\-files"
|
||||
causes
|
||||
.I patch
|
||||
to remove output files that are empty after the patches have been applied.
|
||||
.TP 5
|
||||
.B "\-f, \-\-force"
|
||||
forces
|
||||
.I patch
|
||||
to assume that the user knows exactly what he or she is doing, and to not
|
||||
ask any questions. It assumes the following: skip patches for which a
|
||||
file to patch can't be found; patch files even though they have the
|
||||
wrong version for the ``Prereq:'' line in the patch; and assume that
|
||||
patches are not reversed even if they look like they are.
|
||||
This option does not suppress commentary; use
|
||||
.B \-s
|
||||
for that.
|
||||
.TP 5
|
||||
.B "\-t, \-\-batch"
|
||||
similar to
|
||||
.BR \-f ,
|
||||
in that it suppresses questions, but makes some different assumptions:
|
||||
skip patches for which a file to patch can't be found (the same as \fB\-f\fP);
|
||||
skip patches for which the file has the wrong version for the ``Prereq:'' line
|
||||
in the patch; and assume that patches are reversed if they look like
|
||||
they are.
|
||||
.TP 5
|
||||
.B "\-F number, \-\-fuzz=number"
|
||||
sets the maximum fuzz factor.
|
||||
This option only applies to context diffs, and causes
|
||||
.I patch
|
||||
to ignore up to that many lines in looking for places to install a hunk.
|
||||
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 5
|
||||
.B "\-l, \-\-ignore\-whitespace"
|
||||
causes the pattern matching to be done loosely, in case the tabs and
|
||||
spaces have been munged in your input file.
|
||||
Any sequence of whitespace in the pattern line will match any sequence
|
||||
in the input file.
|
||||
Normal characters must still match exactly.
|
||||
Each line of the context must still match a line in the input file.
|
||||
.TP 5
|
||||
.B "\-n, \-\-normal"
|
||||
forces
|
||||
.I patch
|
||||
to interpret the patch file as a normal diff.
|
||||
.TP 5
|
||||
.B "\-N, \-\-forward"
|
||||
causes
|
||||
.I patch
|
||||
to ignore patches that it thinks are reversed or already applied.
|
||||
See also
|
||||
.B \-R .
|
||||
.TP 5
|
||||
.B "\-o file, \-\-output=file"
|
||||
causes
|
||||
.B file
|
||||
to be interpreted as the output file name.
|
||||
.TP 5
|
||||
.B "\-p[number], \-\-strip[=number]"
|
||||
sets the pathname strip count,
|
||||
which controls how pathnames found in the patch file are treated, in case
|
||||
the you keep your files in a different directory than the person who sent
|
||||
out the patch.
|
||||
The strip count specifies how many slashes are to be stripped from
|
||||
the front of the pathname.
|
||||
(Any intervening directory names also go away.)
|
||||
For example, supposing the file name in the patch file was
|
||||
.sp
|
||||
/u/howard/src/blurfl/blurfl.c
|
||||
.sp
|
||||
setting
|
||||
.B \-p
|
||||
or
|
||||
.B \-p0
|
||||
gives the entire pathname unmodified,
|
||||
.B \-p1
|
||||
gives
|
||||
.sp
|
||||
u/howard/src/blurfl/blurfl.c
|
||||
.sp
|
||||
without the leading slash,
|
||||
.B \-p4
|
||||
gives
|
||||
.sp
|
||||
blurfl/blurfl.c
|
||||
.sp
|
||||
and not specifying
|
||||
.B \-p
|
||||
at all just gives you "blurfl.c", unless all of the directories in the
|
||||
leading path (u/howard/src/blurfl) exist and that path is relative,
|
||||
in which case you get the entire pathname unmodified.
|
||||
Whatever you end up with is looked for either in the current directory,
|
||||
or the directory specified by the
|
||||
.B \-d
|
||||
option.
|
||||
.TP 5
|
||||
.B "\-r file, \-\-reject\-file=file"
|
||||
causes
|
||||
.B file
|
||||
to be interpreted as the reject file name.
|
||||
.TP 5
|
||||
.B "\-R, \-\-reverse"
|
||||
tells
|
||||
.I patch
|
||||
that this patch was created with the old and new files swapped.
|
||||
(Yes, I'm afraid that does happen occasionally, human nature being what it
|
||||
is.)
|
||||
.I Patch
|
||||
will attempt to swap each hunk around before applying it.
|
||||
Rejects will come out in the swapped format.
|
||||
The
|
||||
.B \-R
|
||||
option will not work with
|
||||
.I ed
|
||||
diff scripts because there is too little
|
||||
information to reconstruct the reverse operation.
|
||||
.Sp
|
||||
If the first hunk of a patch fails,
|
||||
.I patch
|
||||
will reverse the hunk to see if it can be applied that way.
|
||||
If it can, you will be asked if you want to have the
|
||||
.B \-R
|
||||
option set.
|
||||
If it can't, the patch will continue to be applied normally.
|
||||
(Note: this method cannot detect a reversed patch if it is a normal diff
|
||||
and if the first command is an append (i.e. it should have been a delete)
|
||||
since appends always succeed, due to the fact that a null context will match
|
||||
anywhere.
|
||||
Luckily, most patches add or change lines rather than delete them, so most
|
||||
reversed normal diffs will begin with a delete, which will fail, triggering
|
||||
the heuristic.)
|
||||
.TP 5
|
||||
.B "\-s, \-\-silent, \-\-quiet"
|
||||
makes
|
||||
.I patch
|
||||
do its work silently, unless an error occurs.
|
||||
.TP 5
|
||||
.B "\-S, \-\-skip"
|
||||
causes
|
||||
.I patch
|
||||
to ignore this patch from the patch file, but continue on looking
|
||||
for the next patch in the file.
|
||||
Thus
|
||||
.sp
|
||||
patch -S + -S + <patchfile
|
||||
.sp
|
||||
will ignore the first and second of three patches.
|
||||
.TP 5
|
||||
.B "\-u, \-\-unified"
|
||||
forces
|
||||
.I patch
|
||||
to interpret the patch file as a unified context diff (a unidiff).
|
||||
.TP 5
|
||||
.B "\-v, \-\-version"
|
||||
causes
|
||||
.I patch
|
||||
to print out its revision header and patch level.
|
||||
.TP 5
|
||||
.B "\-V method, \-\-version\-\-control=method"
|
||||
causes
|
||||
.B method
|
||||
to be interpreted as a method for creating
|
||||
backup file names. The type of backups made can also be given in the
|
||||
.B VERSION_CONTROL
|
||||
environment variable, which is overridden by this option.
|
||||
The
|
||||
.B -B
|
||||
option overrides this option, causing the prefix to always be used for
|
||||
making backup file names.
|
||||
The value of the
|
||||
.B VERSION_CONTROL
|
||||
environment variable and the argument to the
|
||||
.B -V
|
||||
option are like the GNU
|
||||
Emacs `version-control' variable; they also recognize synonyms that
|
||||
are more descriptive. The valid values are (unique abbreviations are
|
||||
accepted):
|
||||
.RS
|
||||
.TP
|
||||
`t' or `numbered'
|
||||
Always make numbered backups.
|
||||
.TP
|
||||
`nil' or `existing'
|
||||
Make numbered backups of files that already
|
||||
have them, simple backups of the others.
|
||||
This is the default.
|
||||
.TP
|
||||
`never' or `simple'
|
||||
Always make simple backups.
|
||||
.RE
|
||||
.TP 5
|
||||
.B "\-x number, \-\-debug=number"
|
||||
sets internal debugging flags, and is of interest only to
|
||||
.I patch
|
||||
patchers.
|
||||
.SH AUTHOR
|
||||
Larry Wall <lwall@netlabs.com>
|
||||
.br
|
||||
with many other contributors.
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B TMPDIR
|
||||
Directory to put temporary files in; default is /tmp.
|
||||
.TP
|
||||
.B SIMPLE_BACKUP_SUFFIX
|
||||
Extension to use for backup file names instead of \*(L".orig\*(R" or
|
||||
\*(L"~\*(R".
|
||||
.TP
|
||||
.B VERSION_CONTROL
|
||||
Selects when numbered backup files are made.
|
||||
.SH FILES
|
||||
$TMPDIR/patch*
|
||||
.SH SEE ALSO
|
||||
diff(1)
|
||||
.SH NOTES FOR PATCH SENDERS
|
||||
There are several things you should bear in mind if you are going to
|
||||
be sending out patches.
|
||||
First, you can save people a lot of grief by keeping a patchlevel.h file
|
||||
which is patched to increment the patch level as the first diff in the
|
||||
patch file you send out.
|
||||
If you put a Prereq: line in with the patch, it won't let them apply
|
||||
patches out of order without some warning.
|
||||
Second, make sure you've specified the file names right, either in a
|
||||
context diff header, or with an Index: line.
|
||||
If you are patching something in a subdirectory, be sure to tell the patch
|
||||
user to specify a
|
||||
.B \-p
|
||||
option as needed.
|
||||
Third, you can create a file by sending out a diff that compares a
|
||||
null file to the file you want to create.
|
||||
This will only work if the file you want to create doesn't exist already in
|
||||
the target directory.
|
||||
Fourth, take care not to send out reversed patches, since it makes people wonder
|
||||
whether they already applied the patch.
|
||||
Fifth, while you may be able to get away with putting 582 diff listings into
|
||||
one file, it is probably wiser to group related patches into separate files in
|
||||
case something goes haywire.
|
||||
.SH DIAGNOSTICS
|
||||
Too many to list here, but generally indicative that
|
||||
.I patch
|
||||
couldn't parse your patch file.
|
||||
.PP
|
||||
The message \*(L"Hmm...\*(R" indicates that there is unprocessed text in
|
||||
the patch file and that
|
||||
.I patch
|
||||
is attempting to intuit whether there is a patch in that text and, if so,
|
||||
what kind of patch it is.
|
||||
.PP
|
||||
.I Patch
|
||||
will exit with a non-zero status if any reject files were created.
|
||||
When applying a set of patches in a loop it behooves you to check this
|
||||
exit status so you don't apply a later patch to a partially patched file.
|
||||
.SH CAVEATS
|
||||
.I Patch
|
||||
cannot tell if the line numbers are off in an
|
||||
.I ed
|
||||
script, and can only detect
|
||||
bad line numbers in a normal diff when it finds a \*(L"change\*(R" or
|
||||
a \*(L"delete\*(R" command.
|
||||
A context diff using fuzz factor 3 may have the same problem.
|
||||
Until a suitable interactive interface is added, you should probably do
|
||||
a context diff in these cases to see if the changes made sense.
|
||||
Of course, compiling without errors is a pretty good indication that the patch
|
||||
worked, but not always.
|
||||
.PP
|
||||
.I Patch
|
||||
usually produces the correct results, even when it has to do a lot of
|
||||
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 BUGS
|
||||
Could be smarter about partial matches, excessively \&deviant offsets and
|
||||
swapped code, but that would take an extra pass.
|
||||
.PP
|
||||
If code has been duplicated (for instance with #ifdef OLDCODE ... #else ...
|
||||
#endif),
|
||||
.I patch
|
||||
is incapable of patching both versions, and, if it works at all, will likely
|
||||
patch the wrong one, and tell you that it succeeded to boot.
|
||||
.PP
|
||||
If you apply a patch you've already applied,
|
||||
.I patch
|
||||
will think it is a reversed patch, and offer to un-apply the patch.
|
||||
This could be construed as a feature.
|
||||
.rn }` ''
|
1003
gnu/usr.bin/patch/patch.c
Normal file
1003
gnu/usr.bin/patch/patch.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
||||
#define PATCH_VERSION "2.5"
|
||||
#define PATCH_VERSION "2.1"
|
||||
|
1401
gnu/usr.bin/patch/pch.c
Normal file
1401
gnu/usr.bin/patch/pch.c
Normal file
File diff suppressed because it is too large
Load Diff
42
gnu/usr.bin/patch/pch.h
Normal file
42
gnu/usr.bin/patch/pch.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* $Header: /home/ncvs/src/gnu/usr.bin/patch/pch.h,v 1.2 1995/05/30 05:02:36 rgrimes Exp $
|
||||
*
|
||||
* $Log: pch.h,v $
|
||||
* Revision 1.2 1995/05/30 05:02:36 rgrimes
|
||||
* Remove trailing whitespace.
|
||||
*
|
||||
* Revision 1.1.1.1 1993/06/19 14:21:52 paul
|
||||
* b-maked patch-2.10
|
||||
*
|
||||
* Revision 2.0.1.1 87/01/30 22:47:16 lwall
|
||||
* Added do_ed_script().
|
||||
*
|
||||
* Revision 2.0 86/09/17 15:39:57 lwall
|
||||
* Baseline for netwide release.
|
||||
*
|
||||
*/
|
||||
|
||||
EXT FILE *pfp INIT(Nullfp); /* patch file pointer */
|
||||
|
||||
void re_patch();
|
||||
void open_patch_file();
|
||||
void set_hunkmax();
|
||||
void grow_hunkmax();
|
||||
bool there_is_another_patch();
|
||||
int intuit_diff_type();
|
||||
void next_intuit_at();
|
||||
void skip_to();
|
||||
bool another_hunk();
|
||||
bool pch_swap();
|
||||
char *pfetch();
|
||||
short pch_line_len();
|
||||
LINENUM pch_first();
|
||||
LINENUM pch_ptrn_lines();
|
||||
LINENUM pch_newfirst();
|
||||
LINENUM pch_repl_lines();
|
||||
LINENUM pch_end();
|
||||
LINENUM pch_context();
|
||||
LINENUM pch_hunk_beg();
|
||||
char pch_char();
|
||||
char *pfetch();
|
||||
char *pgets();
|
||||
void do_ed_script();
|
440
gnu/usr.bin/patch/util.c
Normal file
440
gnu/usr.bin/patch/util.c
Normal file
@ -0,0 +1,440 @@
|
||||
#include "EXTERN.h"
|
||||
#include "common.h"
|
||||
#include "INTERN.h"
|
||||
#include "util.h"
|
||||
#include "backupfile.h"
|
||||
|
||||
void my_exit();
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
static char *
|
||||
private_strerror (errnum)
|
||||
int errnum;
|
||||
{
|
||||
extern char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
|
||||
if (errnum > 0 && errnum <= sys_nerr)
|
||||
return sys_errlist[errnum];
|
||||
return "Unknown system error";
|
||||
}
|
||||
#define strerror private_strerror
|
||||
#endif /* !HAVE_STRERROR */
|
||||
|
||||
/* Rename a file, copying it if necessary. */
|
||||
|
||||
int
|
||||
move_file(from,to)
|
||||
char *from, *to;
|
||||
{
|
||||
char bakname[512];
|
||||
Reg1 char *s;
|
||||
Reg2 int i;
|
||||
Reg3 int fromfd;
|
||||
|
||||
/* to stdout? */
|
||||
|
||||
if (strEQ(to, "-")) {
|
||||
#ifdef DEBUGGING
|
||||
if (debug & 4)
|
||||
say2("Moving %s to stdout.\n", from);
|
||||
#endif
|
||||
fromfd = open(from, 0);
|
||||
if (fromfd < 0)
|
||||
pfatal2("internal error, can't reopen %s", from);
|
||||
while ((i=read(fromfd, buf, sizeof buf)) > 0)
|
||||
if (write(1, buf, i) != 1)
|
||||
pfatal1("write failed");
|
||||
Close(fromfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (origprae) {
|
||||
Strcpy(bakname, origprae);
|
||||
Strcat(bakname, to);
|
||||
} else {
|
||||
#ifndef NODIR
|
||||
char *backupname = find_backup_file_name(to);
|
||||
if (backupname == (char *) 0)
|
||||
fatal1("out of memory\n");
|
||||
Strcpy(bakname, backupname);
|
||||
free(backupname);
|
||||
#else /* NODIR */
|
||||
Strcpy(bakname, to);
|
||||
Strcat(bakname, simple_backup_suffix);
|
||||
#endif /* NODIR */
|
||||
}
|
||||
|
||||
if (stat(to, &filestat) == 0) { /* output file exists */
|
||||
dev_t to_device = filestat.st_dev;
|
||||
ino_t to_inode = filestat.st_ino;
|
||||
char *simplename = bakname;
|
||||
|
||||
for (s=bakname; *s; s++) {
|
||||
if (*s == '/')
|
||||
simplename = s+1;
|
||||
}
|
||||
/* Find a backup name that is not the same file.
|
||||
Change the first lowercase char into uppercase;
|
||||
if that isn't sufficient, chop off the first char and try again. */
|
||||
while (stat(bakname, &filestat) == 0 &&
|
||||
to_device == filestat.st_dev && to_inode == filestat.st_ino) {
|
||||
/* Skip initial non-lowercase chars. */
|
||||
for (s=simplename; *s && !islower((unsigned char)*s); s++) ;
|
||||
if (*s)
|
||||
*s = toupper((unsigned char)*s);
|
||||
else
|
||||
Strcpy(simplename, simplename+1);
|
||||
}
|
||||
while (unlink(bakname) >= 0) ; /* while() is for benefit of Eunice */
|
||||
#ifdef DEBUGGING
|
||||
if (debug & 4)
|
||||
say3("Moving %s to %s.\n", to, bakname);
|
||||
#endif
|
||||
if (rename(to, bakname) < 0) {
|
||||
say4("Can't backup %s, output is in %s: %s\n", to, from,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
while (unlink(to) >= 0) ;
|
||||
}
|
||||
#ifdef DEBUGGING
|
||||
if (debug & 4)
|
||||
say3("Moving %s to %s.\n", from, to);
|
||||
#endif
|
||||
if (rename(from, to) < 0) { /* different file system? */
|
||||
Reg4 int tofd;
|
||||
|
||||
tofd = creat(to, 0666);
|
||||
if (tofd < 0) {
|
||||
say4("Can't create %s, output is in %s: %s\n",
|
||||
to, from, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
fromfd = open(from, 0);
|
||||
if (fromfd < 0)
|
||||
pfatal2("internal error, can't reopen %s", from);
|
||||
while ((i=read(fromfd, buf, sizeof buf)) > 0)
|
||||
if (write(tofd, buf, i) != i)
|
||||
pfatal1("write failed");
|
||||
Close(fromfd);
|
||||
Close(tofd);
|
||||
}
|
||||
Unlink(from);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy a file. */
|
||||
|
||||
void
|
||||
copy_file(from,to)
|
||||
char *from, *to;
|
||||
{
|
||||
Reg3 int tofd;
|
||||
Reg2 int fromfd;
|
||||
Reg1 int i;
|
||||
|
||||
tofd = creat(to, 0666);
|
||||
if (tofd < 0)
|
||||
pfatal2("can't create %s", to);
|
||||
fromfd = open(from, 0);
|
||||
if (fromfd < 0)
|
||||
pfatal2("internal error, can't reopen %s", from);
|
||||
while ((i=read(fromfd, buf, sizeof buf)) > 0)
|
||||
if (write(tofd, buf, i) != i)
|
||||
pfatal2("write to %s failed", to);
|
||||
Close(fromfd);
|
||||
Close(tofd);
|
||||
}
|
||||
|
||||
/* Allocate a unique area for a string. */
|
||||
|
||||
char *
|
||||
savestr(s)
|
||||
Reg1 char *s;
|
||||
{
|
||||
Reg3 char *rv;
|
||||
Reg2 char *t;
|
||||
|
||||
if (!s)
|
||||
s = "Oops";
|
||||
t = s;
|
||||
while (*t++);
|
||||
rv = malloc((MEM) (t - s));
|
||||
if (rv == Nullch) {
|
||||
if (using_plan_a)
|
||||
out_of_mem = TRUE;
|
||||
else
|
||||
fatal1("out of memory\n");
|
||||
}
|
||||
else {
|
||||
t = rv;
|
||||
while ((*t++ = *s++));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if defined(lint) && defined(CANVARARG)
|
||||
|
||||
/*VARARGS ARGSUSED*/
|
||||
say(pat) char *pat; { ; }
|
||||
/*VARARGS ARGSUSED*/
|
||||
fatal(pat) char *pat; { ; }
|
||||
/*VARARGS ARGSUSED*/
|
||||
pfatal(pat) char *pat; { ; }
|
||||
/*VARARGS ARGSUSED*/
|
||||
ask(pat) char *pat; { ; }
|
||||
|
||||
#else
|
||||
|
||||
/* Vanilla terminal output (buffered). */
|
||||
|
||||
void
|
||||
say(pat,arg1,arg2,arg3)
|
||||
char *pat;
|
||||
long arg1,arg2,arg3;
|
||||
{
|
||||
fprintf(stderr, pat, arg1, arg2, arg3);
|
||||
Fflush(stderr);
|
||||
}
|
||||
|
||||
/* Terminal output, pun intended. */
|
||||
|
||||
void /* very void */
|
||||
fatal(pat,arg1,arg2,arg3)
|
||||
char *pat;
|
||||
long arg1,arg2,arg3;
|
||||
{
|
||||
fprintf(stderr, "patch: **** ");
|
||||
fprintf(stderr, pat, arg1, arg2, arg3);
|
||||
my_exit(1);
|
||||
}
|
||||
|
||||
/* Say something from patch, something from the system, then silence . . . */
|
||||
|
||||
void /* very void */
|
||||
pfatal(pat,arg1,arg2,arg3)
|
||||
char *pat;
|
||||
long arg1,arg2,arg3;
|
||||
{
|
||||
int errnum = errno;
|
||||
|
||||
fprintf(stderr, "patch: **** ");
|
||||
fprintf(stderr, pat, arg1, arg2, arg3);
|
||||
fprintf(stderr, ": %s\n", strerror(errnum));
|
||||
my_exit(1);
|
||||
}
|
||||
|
||||
/* Get a response from the user, somehow or other. */
|
||||
|
||||
int
|
||||
ask(pat,arg1,arg2,arg3)
|
||||
char *pat;
|
||||
long arg1,arg2,arg3;
|
||||
{
|
||||
int ttyfd;
|
||||
int r;
|
||||
bool tty2 = isatty(2);
|
||||
|
||||
Sprintf(buf, pat, arg1, arg2, arg3);
|
||||
Fflush(stderr);
|
||||
write(2, buf, strlen(buf));
|
||||
if (tty2) { /* might be redirected to a file */
|
||||
r = read(2, buf, sizeof buf);
|
||||
}
|
||||
else if (isatty(1)) { /* this may be new file output */
|
||||
Fflush(stdout);
|
||||
write(1, buf, strlen(buf));
|
||||
r = read(1, buf, sizeof buf);
|
||||
}
|
||||
else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
|
||||
/* might be deleted or unwriteable */
|
||||
write(ttyfd, buf, strlen(buf));
|
||||
r = read(ttyfd, buf, sizeof buf);
|
||||
Close(ttyfd);
|
||||
}
|
||||
else if (isatty(0)) { /* this is probably patch input */
|
||||
Fflush(stdin);
|
||||
write(0, buf, strlen(buf));
|
||||
r = read(0, buf, sizeof buf);
|
||||
}
|
||||
else { /* no terminal at all--default it */
|
||||
buf[0] = '\n';
|
||||
buf[1] = 0;
|
||||
say1(buf);
|
||||
return 0; /* signal possible error */
|
||||
}
|
||||
if (r <= 0)
|
||||
buf[0] = 0;
|
||||
else
|
||||
buf[r] = '\0';
|
||||
if (!tty2)
|
||||
say1(buf);
|
||||
|
||||
if (r <= 0)
|
||||
return 0; /* if there was an error, return it */
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
#endif /* lint */
|
||||
|
||||
/* How to handle certain events when not in a critical region. */
|
||||
|
||||
void
|
||||
set_signals(reset)
|
||||
int reset;
|
||||
{
|
||||
#ifndef lint
|
||||
static RETSIGTYPE (*hupval)(),(*intval)();
|
||||
|
||||
if (!reset) {
|
||||
hupval = signal(SIGHUP, SIG_IGN);
|
||||
if (hupval != SIG_IGN)
|
||||
hupval = (RETSIGTYPE(*)())my_exit;
|
||||
intval = signal(SIGINT, SIG_IGN);
|
||||
if (intval != SIG_IGN)
|
||||
intval = (RETSIGTYPE(*)())my_exit;
|
||||
}
|
||||
Signal(SIGHUP, hupval);
|
||||
Signal(SIGINT, intval);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* How to handle certain events when in a critical region. */
|
||||
|
||||
void
|
||||
ignore_signals()
|
||||
{
|
||||
#ifndef lint
|
||||
Signal(SIGHUP, SIG_IGN);
|
||||
Signal(SIGINT, SIG_IGN);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Make sure we'll have the directories to create a file.
|
||||
If `striplast' is TRUE, ignore the last element of `filename'. */
|
||||
|
||||
void
|
||||
makedirs(filename,striplast)
|
||||
Reg1 char *filename;
|
||||
bool striplast;
|
||||
{
|
||||
char tmpbuf[256];
|
||||
Reg2 char *s = tmpbuf;
|
||||
char *dirv[20]; /* Point to the NULs between elements. */
|
||||
Reg3 int i;
|
||||
Reg4 int dirvp = 0; /* Number of finished entries in dirv. */
|
||||
|
||||
/* Copy `filename' into `tmpbuf' with a NUL instead of a slash
|
||||
between the directories. */
|
||||
while (*filename) {
|
||||
if (*filename == '/') {
|
||||
filename++;
|
||||
dirv[dirvp++] = s;
|
||||
*s++ = '\0';
|
||||
}
|
||||
else {
|
||||
*s++ = *filename++;
|
||||
}
|
||||
}
|
||||
*s = '\0';
|
||||
dirv[dirvp] = s;
|
||||
if (striplast)
|
||||
dirvp--;
|
||||
if (dirvp < 0)
|
||||
return;
|
||||
|
||||
strcpy(buf, "mkdir");
|
||||
s = buf;
|
||||
for (i=0; i<=dirvp; i++) {
|
||||
struct stat sbuf;
|
||||
|
||||
if (stat(tmpbuf, &sbuf) && errno == ENOENT) {
|
||||
while (*s) s++;
|
||||
*s++ = ' ';
|
||||
strcpy(s, tmpbuf);
|
||||
}
|
||||
*dirv[i] = '/';
|
||||
}
|
||||
if (s != buf)
|
||||
system(buf);
|
||||
}
|
||||
|
||||
/* Make filenames more reasonable. */
|
||||
|
||||
char *
|
||||
fetchname(at,strip_leading,assume_exists)
|
||||
char *at;
|
||||
int strip_leading;
|
||||
int assume_exists;
|
||||
{
|
||||
char *fullname;
|
||||
char *name;
|
||||
Reg1 char *t;
|
||||
char tmpbuf[200];
|
||||
int sleading = strip_leading;
|
||||
|
||||
if (!at)
|
||||
return Nullch;
|
||||
while (isspace((unsigned char)*at))
|
||||
at++;
|
||||
#ifdef DEBUGGING
|
||||
if (debug & 128)
|
||||
say4("fetchname %s %d %d\n",at,strip_leading,assume_exists);
|
||||
#endif
|
||||
if (strnEQ(at, "/dev/null", 9)) /* so files can be created by diffing */
|
||||
return Nullch; /* against /dev/null. */
|
||||
name = fullname = t = savestr(at);
|
||||
|
||||
/* Strip off up to `sleading' leading slashes and null terminate. */
|
||||
for (; *t && !isspace((unsigned char)*t); t++)
|
||||
if (*t == '/')
|
||||
if (--sleading >= 0)
|
||||
name = t+1;
|
||||
*t = '\0';
|
||||
|
||||
/* If no -p option was given (957 is the default value!),
|
||||
we were given a relative pathname,
|
||||
and the leading directories that we just stripped off all exist,
|
||||
put them back on. */
|
||||
if (strip_leading == 957 && name != fullname && *fullname != '/') {
|
||||
name[-1] = '\0';
|
||||
if (stat(fullname, &filestat) == 0 && S_ISDIR (filestat.st_mode)) {
|
||||
name[-1] = '/';
|
||||
name=fullname;
|
||||
}
|
||||
}
|
||||
|
||||
name = savestr(name);
|
||||
free(fullname);
|
||||
|
||||
if (stat(name, &filestat) && !assume_exists) {
|
||||
char *filebase = basename(name);
|
||||
int pathlen = filebase - name;
|
||||
|
||||
/* Put any leading path into `tmpbuf'. */
|
||||
strncpy(tmpbuf, name, pathlen);
|
||||
|
||||
#define try(f, a1, a2) (Sprintf(tmpbuf + pathlen, f, a1, a2), stat(tmpbuf, &filestat) == 0)
|
||||
if ( try("RCS/%s%s", filebase, RCSSUFFIX)
|
||||
|| try("RCS/%s%s", filebase, "")
|
||||
|| try( "%s%s", filebase, RCSSUFFIX)
|
||||
|| try("SCCS/%s%s", SCCSPREFIX, filebase)
|
||||
|| try( "%s%s", SCCSPREFIX, filebase))
|
||||
return name;
|
||||
free(name);
|
||||
name = Nullch;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
char *
|
||||
xmalloc (size)
|
||||
unsigned size;
|
||||
{
|
||||
register char *p = (char *) malloc (size);
|
||||
if (!p)
|
||||
fatal("out of memory");
|
||||
return p;
|
||||
}
|
107
gnu/usr.bin/patch/util.h
Normal file
107
gnu/usr.bin/patch/util.h
Normal file
@ -0,0 +1,107 @@
|
||||
/* $Header: /home/ncvs/src/gnu/usr.bin/patch/util.h,v 1.3 1997/02/13 21:10:45 jmg Exp $
|
||||
*
|
||||
* $Log: util.h,v $
|
||||
* Revision 1.3 1997/02/13 21:10:45 jmg
|
||||
* Fix a problem with patch in that is will always default, even when the
|
||||
* controlling terminal is closed. Now the function ask() will return 1 when th
|
||||
* input is known to come from a file or terminal, or it will return 0 when ther
|
||||
* was a read error.
|
||||
*
|
||||
* Modified the question "Skip patch?" so that on an error from ask it will skip
|
||||
* the patch instead of looping.
|
||||
*
|
||||
* Closes PR#777
|
||||
*
|
||||
* 2.2 candidate
|
||||
*
|
||||
* Revision 1.2 1995/05/30 05:02:38 rgrimes
|
||||
* Remove trailing whitespace.
|
||||
*
|
||||
* Revision 1.1.1.1 1993/06/19 14:21:52 paul
|
||||
* b-maked patch-2.10
|
||||
*
|
||||
* Revision 2.0 86/09/17 15:40:06 lwall
|
||||
* Baseline for netwide release.
|
||||
*
|
||||
*/
|
||||
|
||||
/* and for those machine that can't handle a variable argument list */
|
||||
|
||||
#ifdef CANVARARG
|
||||
|
||||
#define say1 say
|
||||
#define say2 say
|
||||
#define say3 say
|
||||
#define say4 say
|
||||
#define ask1 ask
|
||||
#define ask2 ask
|
||||
#define ask3 ask
|
||||
#define ask4 ask
|
||||
#define fatal1 fatal
|
||||
#define fatal2 fatal
|
||||
#define fatal3 fatal
|
||||
#define fatal4 fatal
|
||||
#define pfatal1 pfatal
|
||||
#define pfatal2 pfatal
|
||||
#define pfatal3 pfatal
|
||||
#define pfatal4 pfatal
|
||||
|
||||
#else /* hope they allow multi-line macro actual arguments */
|
||||
|
||||
#ifdef lint
|
||||
|
||||
#define say1(a) say(a, 0, 0, 0)
|
||||
#define say2(a,b) say(a, (b)==(b), 0, 0)
|
||||
#define say3(a,b,c) say(a, (b)==(b), (c)==(c), 0)
|
||||
#define say4(a,b,c,d) say(a, (b)==(b), (c)==(c), (d)==(d))
|
||||
#define ask1(a) ask(a, 0, 0, 0)
|
||||
#define ask2(a,b) ask(a, (b)==(b), 0, 0)
|
||||
#define ask3(a,b,c) ask(a, (b)==(b), (c)==(c), 0)
|
||||
#define ask4(a,b,c,d) ask(a, (b)==(b), (c)==(c), (d)==(d))
|
||||
#define fatal1(a) fatal(a, 0, 0, 0)
|
||||
#define fatal2(a,b) fatal(a, (b)==(b), 0, 0)
|
||||
#define fatal3(a,b,c) fatal(a, (b)==(b), (c)==(c), 0)
|
||||
#define fatal4(a,b,c,d) fatal(a, (b)==(b), (c)==(c), (d)==(d))
|
||||
#define pfatal1(a) pfatal(a, 0, 0, 0)
|
||||
#define pfatal2(a,b) pfatal(a, (b)==(b), 0, 0)
|
||||
#define pfatal3(a,b,c) pfatal(a, (b)==(b), (c)==(c), 0)
|
||||
#define pfatal4(a,b,c,d) pfatal(a, (b)==(b), (c)==(c), (d)==(d))
|
||||
|
||||
#else /* lint */
|
||||
/* if this doesn't work, try defining CANVARARG above */
|
||||
#define say1(a) say(a, Nullch, Nullch, Nullch)
|
||||
#define say2(a,b) say(a, b, Nullch, Nullch)
|
||||
#define say3(a,b,c) say(a, b, c, Nullch)
|
||||
#define say4 say
|
||||
#define ask1(a) ask(a, Nullch, Nullch, Nullch)
|
||||
#define ask2(a,b) ask(a, b, Nullch, Nullch)
|
||||
#define ask3(a,b,c) ask(a, b, c, Nullch)
|
||||
#define ask4 ask
|
||||
#define fatal1(a) fatal(a, Nullch, Nullch, Nullch)
|
||||
#define fatal2(a,b) fatal(a, b, Nullch, Nullch)
|
||||
#define fatal3(a,b,c) fatal(a, b, c, Nullch)
|
||||
#define fatal4 fatal
|
||||
#define pfatal1(a) pfatal(a, Nullch, Nullch, Nullch)
|
||||
#define pfatal2(a,b) pfatal(a, b, Nullch, Nullch)
|
||||
#define pfatal3(a,b,c) pfatal(a, b, c, Nullch)
|
||||
#define pfatal4 pfatal
|
||||
|
||||
#endif /* lint */
|
||||
|
||||
/* if neither of the above work, join all multi-line macro calls. */
|
||||
#endif
|
||||
|
||||
EXT char serrbuf[BUFSIZ]; /* buffer for stderr */
|
||||
|
||||
char *fetchname();
|
||||
int move_file();
|
||||
void copy_file();
|
||||
void say();
|
||||
void fatal();
|
||||
void pfatal();
|
||||
int ask();
|
||||
char *savestr();
|
||||
void set_signals();
|
||||
void ignore_signals();
|
||||
void makedirs();
|
||||
char *basename();
|
31
gnu/usr.bin/patch/version.c
Normal file
31
gnu/usr.bin/patch/version.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* $Header: /home/ncvs/src/gnu/usr.bin/patch/version.c,v 1.2 1995/05/30 05:02:39 rgrimes Exp $
|
||||
*
|
||||
* $Log: version.c,v $
|
||||
* Revision 1.2 1995/05/30 05:02:39 rgrimes
|
||||
* Remove trailing whitespace.
|
||||
*
|
||||
* Revision 1.1.1.1 1993/06/19 14:21:52 paul
|
||||
* b-maked patch-2.10
|
||||
*
|
||||
* Revision 2.0 86/09/17 15:40:11 lwall
|
||||
* Baseline for netwide release.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EXTERN.h"
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "INTERN.h"
|
||||
#include "patchlevel.h"
|
||||
#include "version.h"
|
||||
|
||||
void my_exit();
|
||||
|
||||
/* Print out the version number and die. */
|
||||
|
||||
void
|
||||
version()
|
||||
{
|
||||
fprintf(stderr, "Patch version %s\n", PATCH_VERSION);
|
||||
my_exit(0);
|
||||
}
|
15
gnu/usr.bin/patch/version.h
Normal file
15
gnu/usr.bin/patch/version.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* $Header: /home/ncvs/src/gnu/usr.bin/patch/version.h,v 1.2 1995/05/30 05:02:40 rgrimes Exp $
|
||||
*
|
||||
* $Log: version.h,v $
|
||||
* Revision 1.2 1995/05/30 05:02:40 rgrimes
|
||||
* Remove trailing whitespace.
|
||||
*
|
||||
* Revision 1.1.1.1 1993/06/19 14:21:52 paul
|
||||
* b-maked patch-2.10
|
||||
*
|
||||
* Revision 2.0 86/09/17 15:40:14 lwall
|
||||
* Baseline for netwide release.
|
||||
*
|
||||
*/
|
||||
|
||||
void version();
|
Loading…
Reference in New Issue
Block a user