diff options
Diffstat (limited to 'gnu/usr.bin/rcs/lib')
-rw-r--r-- | gnu/usr.bin/rcs/lib/Makefile | 14 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/conf.h | 400 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/maketime.c | 344 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/maketime.h | 39 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/merger.c | 148 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/partime.c | 701 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/partime.h | 71 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcsbase.h | 762 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcsedit.c | 1958 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcsfcmp.c | 354 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcsfnms.c | 1132 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcsgen.c | 681 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcskeep.c | 452 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcskeys.c | 186 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcslex.c | 1568 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcsmap.c | 69 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcsrev.c | 911 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcssyn.c | 681 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcstime.c | 191 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/rcsutil.c | 1398 | ||||
-rw-r--r-- | gnu/usr.bin/rcs/lib/version.c | 2 |
21 files changed, 0 insertions, 12062 deletions
diff --git a/gnu/usr.bin/rcs/lib/Makefile b/gnu/usr.bin/rcs/lib/Makefile deleted file mode 100644 index f21fda1..0000000 --- a/gnu/usr.bin/rcs/lib/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ - -# Define FSYNC_ALL to get slower but safer writes in case of crashes in -# the middle of CVS/RCS changes -#CFLAGS += -DFSYNC_ALL - -LIB = rcs -SRCS = maketime.c partime.c rcsedit.c rcsfcmp.c rcsfnms.c rcsgen.c \ - rcskeep.c rcskeys.c rcslex.c rcsmap.c rcsrev.c rcssyn.c rcstime.c \ - rcsutil.c merger.c version.c - -INTERNALLIB= - -.include <bsd.lib.mk> diff --git a/gnu/usr.bin/rcs/lib/conf.h b/gnu/usr.bin/rcs/lib/conf.h deleted file mode 100644 index 96ec07d..0000000 --- a/gnu/usr.bin/rcs/lib/conf.h +++ /dev/null @@ -1,400 +0,0 @@ -/* RCS compile-time configuration */ - - /* $FreeBSD$ */ - -/* - * This file is generated automatically. - * If you edit it by hand your changes may be lost. - * Instead, please try to fix conf.sh, - * and send your fixes to rcs-bugs@cs.purdue.edu. - */ - -#define exitmain(n) return n /* how to exit from main() */ -/* #define _POSIX_C_SOURCE 2147483647L */ /* if strict C + Posix 1003.1b-1993 or later */ -/* #define _POSIX_SOURCE */ /* if strict C + Posix 1003.1-1990 */ - -#include <errno.h> -#include <stdio.h> -#include <time.h> - -/* Comment out #include lines below that do not work. */ -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <fcntl.h> -#include <limits.h> -/* #include <mach/mach.h> */ -/* #include <net/errno.h> */ -#include <pwd.h> -/* #include <siginfo.h> */ -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/wait.h> -/* #include <ucontext.h> */ -#include <unistd.h> -#include <utime.h> -/* #include <vfork.h> */ - -/* Define boolean symbols to be 0 (false, the default), or 1 (true). */ -#define has_sys_param_h 1 /* Does #include <sys/param.h> work? */ -/* extern int errno; */ /* Uncomment if <errno.h> doesn't declare errno. */ -#define has_readlink 1 /* Does readlink() work? */ -#define readlink_isreg_errno EINVAL /* errno after readlink on regular file */ - -#if has_readlink && !defined(MAXSYMLINKS) -# if has_sys_param_h -# include <sys/param.h> -# endif -# ifndef MAXSYMLINKS -# define MAXSYMLINKS 20 /* BSD; not standard yet */ -# endif -#endif - -/* Comment out the typedefs below if the types are already declared. */ -/* Fix any uncommented typedefs that are wrong. */ -/* typedef int mode_t; */ -/* typedef long off_t; */ -/* typedef int pid_t; */ -/* typedef int sig_atomic_t; */ -/* typedef unsigned size_t; */ -/* typedef int ssize_t; */ -/* typedef long time_t; */ -/* typedef int uid_t; */ - -/* Comment out the keyword definitions below if the keywords work. */ -/* #define const */ -/* #define volatile */ - -/* Define boolean symbols to be 0 (false, the default), or 1 (true). */ -#define has_prototypes 1 /* Do function prototypes work? */ -#define has_stdarg 1 /* Does <stdarg.h> work? */ -/* #define has_varargs ? */ /* Does <varargs.h> work? */ -#define va_start_args 2 /* How many args does va_start() take? */ - -#if O_BINARY - /* Text and binary i/o behave differently. */ - /* This is incompatible with Posix and Unix. */ -# define FOPEN_RB "rb" -# define FOPEN_R_WORK (Expand==BINARY_EXPAND ? "r" : "rb") -# define FOPEN_WB "wb" -# define FOPEN_W_WORK (Expand==BINARY_EXPAND ? "w" : "wb") -# define FOPEN_WPLUS_WORK (Expand==BINARY_EXPAND ? "w+" : "w+b") -# define OPEN_O_BINARY O_BINARY -#else - /* - * Text and binary i/o behave the same. - * Omit "b", since some nonstandard hosts reject it. - */ -# define FOPEN_RB "r" -# define FOPEN_R_WORK "r" -# define FOPEN_WB "w" -# define FOPEN_W_WORK "w" -# define FOPEN_WPLUS_WORK "w+" -# define OPEN_O_BINARY 0 -#endif - -/* This may need changing on non-Unix systems (notably DOS). */ -#define OPEN_CREAT_READONLY (S_IRUSR|S_IRGRP|S_IROTH) /* lock file mode */ -#define OPEN_O_LOCK 0 /* extra open flags for creating lock file */ -#define OPEN_O_WRONLY O_WRONLY /* main open flag for creating a lock file */ - -/* Define or comment out the following symbols as needed. */ -#if has_prototypes -# define P(params) params -#else -# define P(params) () -#endif -#if has_stdarg -# include <stdarg.h> -#else -# if has_varargs -# include <varargs.h> -# else - typedef char *va_list; -# define va_dcl int va_alist; -# define va_start(ap) ((ap) = (va_list)&va_alist) -# define va_arg(ap,t) (((t*) ((ap)+=sizeof(t))) [-1]) -# define va_end(ap) -# endif -#endif -#if va_start_args == 2 -# define vararg_start va_start -#else -# define vararg_start(ap,p) va_start(ap) -#endif -#define bad_chmod_close 0 /* Can chmod() close file descriptors? */ -#define bad_creat0 0 /* Do writes fail after creat(f,0)? */ -#define bad_fopen_wplus 0 /* Does fopen(f,"w+") fail to truncate f? */ -#define getlogin_is_secure 0 /* Is getlogin() secure? Usually it's not. */ -#define has_attribute_noreturn 1 /* Does __attribute__((noreturn)) work? */ -#if has_attribute_noreturn -# define exiting __attribute__((noreturn)) -#else -# define exiting -#endif -#define has_dirent 1 /* Do opendir(), readdir(), closedir() work? */ -#define void_closedir 0 /* Does closedir() yield void? */ -#define has_fchmod 1 /* Does fchmod() work? */ -#define has_fflush_input 0 /* Does fflush() work on input files? */ -#define has_fputs 1 /* Does fputs() work? */ -#define has_ftruncate 1 /* Does ftruncate() work? */ -#define has_getuid 1 /* Does getuid() work? */ -#define has_getpwuid 1 /* Does getpwuid() work? */ -#define has_memcmp 1 /* Does memcmp() work? */ -#define has_memcpy 1 /* Does memcpy() work? */ -#define has_memmove 1 /* Does memmove() work? */ -#define has_map_fd 0 /* Does map_fd() work? */ -#define has_mmap 1 /* Does mmap() work on regular files? */ -#define has_madvise 0 /* Does madvise() work? */ -#define mmap_signal SIGBUS /* signal received if you reference nonexistent part of mmapped file */ -#define has_rename 1 /* Does rename() work? */ -#define bad_a_rename 0 /* Does rename(A,B) fail if A is unwritable? */ -#define bad_b_rename 0 /* Does rename(A,B) fail if B is unwritable? */ -#define bad_NFS_rename 0 /* Can rename(A,B) falsely report success? */ -/* typedef int void; */ /* Some ancient compilers need this. */ -#define VOID (void) /* 'VOID e;' discards the value of an expression 'e'. */ -#define has_seteuid 1 /* Does seteuid() work? See ../INSTALL.RCS. */ -#define has_setreuid 0 /* Does setreuid() work? See ../INSTALL.RCS. */ -#define has_setuid 1 /* Does setuid() exist? */ -#define has_sigaction 1 /* Does struct sigaction work? */ -#define has_sa_sigaction 1 /* Does struct sigaction have sa_sigaction? */ -#define has_signal 1 /* Does signal() work? */ -#define signal_type void /* type returned by signal handlers */ -#define sig_zaps_handler 0 /* Must a signal handler reinvoke signal()? */ -/* #define has_sigblock ? */ /* Does sigblock() work? */ -/* #define sigmask(s) (1 << ((s)-1)) */ /* Yield mask for signal number. */ -typedef size_t fread_type; /* type returned by fread() and fwrite() */ -typedef size_t freadarg_type; /* type of their size arguments */ -typedef void *malloc_type; /* type returned by malloc() */ -#define has_getcwd 1 /* Does getcwd() work? */ -/* #define has_getwd ? */ /* Does getwd() work? */ -#define needs_getabsname 0 /* Must we define getabsname? */ -#define has_mktemp 1 /* Does mktemp() work? */ -#define has_mkstemp 1 /* Does mkstemp() work? */ -#define has_NFS 1 /* Might NFS be used? */ -#define has_psiginfo 0 /* Does psiginfo() work? */ -#define has_psignal 1 /* Does psignal() work? */ -/* #define has_si_errno ? */ /* Does siginfo_t have si_errno? */ -/* #define has_sys_siglist ? */ /* Does sys_siglist[] work? */ -/* #define strchr index */ /* Use old-fashioned name for strchr()? */ -/* #define strrchr rindex */ /* Use old-fashioned name for strrchr()? */ -#define bad_unlink 0 /* Does unlink() fail on unwritable files? */ -#define has_vfork 1 /* Does vfork() work? */ -#define has_fork 1 /* Does fork() work? */ -#define has_spawn 0 /* Does spawn*() work? */ -#define has_waitpid 1 /* Does waitpid() work? */ -#define bad_wait_if_SIGCHLD_ignored 0 /* Does ignoring SIGCHLD break wait()? */ -#define RCS_SHELL "/bin/sh" /* shell to run RCS subprograms */ -#define has_printf_dot 1 /* Does "%.2d" print leading 0? */ -#define has_vfprintf 1 /* Does vfprintf() work? */ -#define has_attribute_format_printf 1 /* Does __attribute__((format(printf,N,N+1))) work? */ -#if has_attribute_format_printf -# define printf_string(m, n) __attribute__((format(printf, m, n))) -#else -# define printf_string(m, n) -#endif -#if has_attribute_format_printf && has_attribute_noreturn - /* Work around a bug in GCC 2.5.x. */ -# define printf_string_exiting(m, n) __attribute__((format(printf, m, n), noreturn)) -#else -# define printf_string_exiting(m, n) printf_string(m, n) exiting -#endif -/* #define has__doprintf ? */ /* Does _doprintf() work? */ -/* #define has__doprnt ? */ /* Does _doprnt() work? */ -/* #undef EXIT_FAILURE */ /* Uncomment this if EXIT_FAILURE is broken. */ -#define large_memory 1 /* Can main memory hold entire RCS files? */ -#ifndef LONG_MAX -#define LONG_MAX 2147483647L /* long maximum */ -#endif -/* Do struct stat s and t describe the same file? Answer d if unknown. */ -#define same_file(s,t,d) ((s).st_ino==(t).st_ino && (s).st_dev==(t).st_dev) -#define has_utimbuf 1 /* Does struct utimbuf work? */ -#define CO "/usr/bin/co" /* name of 'co' program */ -#define COMPAT2 0 /* Are version 2 files supported? */ -#define DIFF "/usr/bin/diff" /* name of 'diff' program */ -#define DIFF3 "/usr/bin/diff3" /* name of 'diff3' program */ -#define DIFF3_BIN 1 /* Is diff3 user-visible (not the /usr/lib auxiliary)? */ -#define DIFFFLAGS "-an" /* Make diff output suitable for RCS. */ -#define DIFF_L 1 /* Does diff -L work? */ -#define DIFF_SUCCESS 0 /* DIFF status if no differences are found */ -#define DIFF_FAILURE 1 /* DIFF status if differences are found */ -#define DIFF_TROUBLE 2 /* DIFF status if trouble */ -#define ED "/bin/ed" /* name of 'ed' program (used only if !DIFF3_BIN) */ -#define MERGE "/usr/bin/merge" /* name of 'merge' program */ -#define TMPDIR "/tmp" /* default directory for temporary files */ -#define SLASH '/' /* principal filename separator */ -#define SLASHes '/' /* `case SLASHes:' labels all filename separators */ -#define isSLASH(c) ((c) == SLASH) /* Is arg a filename separator? */ -#define ROOTPATH(p) isSLASH((p)[0]) /* Is p an absolute pathname? */ -#define X_DEFAULT ",v/" /* default value for -x option */ -#define SLASHSLASH_is_SLASH 1 /* Are // and / the same directory? */ -#define ALL_ABSOLUTE 1 /* Do all subprograms satisfy ROOTPATH? */ -#define DIFF_ABSOLUTE 1 /* Is ROOTPATH(DIFF) true? */ -#define SENDMAIL "/usr/sbin/sendmail" /* how to send mail */ -#define TZ_must_be_set 0 /* Must TZ be set for gmtime() to work? */ - - - -/* Adjust the following declarations as needed. */ - - -/* The rest is for the benefit of non-standard, traditional hosts. */ -/* Don't bother to declare functions that in traditional hosts do not appear, */ -/* or are declared in .h files, or return int or void. */ - - -/* traditional BSD */ - -#if has_sys_siglist && !defined(sys_siglist) - extern char const * const sys_siglist[]; -#endif - - -/* Posix (ISO/IEC 9945-1: 1990 / IEEE Std 1003.1-1990) */ - -/* <fcntl.h> */ -#ifdef O_CREAT -# define open_can_creat 1 -#else -# define open_can_creat 0 -# define O_RDONLY 0 -# define O_WRONLY 1 -# define O_RDWR 2 -# define O_CREAT 01000 -# define O_TRUNC 02000 -#endif -#ifndef O_EXCL -#define O_EXCL 0 -#endif - -/* <sys/stat.h> */ -#ifndef S_IRUSR -# ifdef S_IREAD -# define S_IRUSR S_IREAD -# else -# define S_IRUSR 0400 -# endif -# ifdef S_IWRITE -# define S_IWUSR S_IWRITE -# else -# define S_IWUSR (S_IRUSR/2) -# endif -#endif -#ifndef S_IRGRP -# if has_getuid -# define S_IRGRP (S_IRUSR / 0010) -# define S_IWGRP (S_IWUSR / 0010) -# define S_IROTH (S_IRUSR / 0100) -# define S_IWOTH (S_IWUSR / 0100) -# else - /* single user OS -- not Posix or Unix */ -# define S_IRGRP 0 -# define S_IWGRP 0 -# define S_IROTH 0 -# define S_IWOTH 0 -# endif -#endif -#ifndef S_ISREG -#define S_ISREG(n) (((n) & S_IFMT) == S_IFREG) -#endif - -/* <sys/wait.h> */ -#ifndef WEXITSTATUS -#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -#undef WIFEXITED /* Avoid 4.3BSD incompatibility with Posix. */ -#endif -#ifndef WIFEXITED -#define WIFEXITED(stat_val) (((stat_val) & 0377) == 0) -#endif -#ifndef WTERMSIG -#define WTERMSIG(stat_val) ((stat_val) & 0177) -#undef WIFSIGNALED /* Avoid 4.3BSD incompatibility with Posix. */ -#endif -#ifndef WIFSIGNALED -#define WIFSIGNALED(stat_val) ((unsigned)(stat_val) - 1 < 0377) -#endif - -/* <unistd.h> */ -char *getlogin P((void)); -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -# define STDOUT_FILENO 1 -# define STDERR_FILENO 2 -#endif -#if has_fork && !has_vfork -# undef vfork -# define vfork fork -#endif -#if has_getcwd || !has_getwd - char *getcwd P((char*,size_t)); -#else - char *getwd P((char*)); -#endif -#if has_setuid && !has_seteuid -# undef seteuid -# define seteuid setuid -#endif -#if has_spawn -# if ALL_ABSOLUTE -# define spawn_RCS spawnv -# else -# define spawn_RCS spawnvp -# endif -#else -# if ALL_ABSOLUTE -# define exec_RCS execv -# else -# define exec_RCS execvp -# endif -#endif - -/* utime.h */ -#if !has_utimbuf - struct utimbuf { time_t actime, modtime; }; -#endif - - -/* Standard C library */ - -/* <stdio.h> */ -#ifndef L_tmpnam -#define L_tmpnam 32 /* power of 2 > sizeof("/usr/tmp/xxxxxxxxxxxxxxx") */ -#endif -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif -#if has_mktemp - char *mktemp P((char*)); /* traditional */ -#else - char *tmpnam P((char*)); -#endif - -/* <stdlib.h> */ -char *getenv P((char const*)); -void _exit P((int)) exiting; -void exit P((int)) exiting; -malloc_type malloc P((size_t)); -malloc_type realloc P((malloc_type,size_t)); -#ifndef EXIT_FAILURE -#define EXIT_FAILURE 1 -#endif -#ifndef EXIT_SUCCESS -#define EXIT_SUCCESS 0 -#endif - -/* <string.h> */ -char *strcpy P((char*,char const*)); -char *strchr P((char const*,int)); -char *strrchr P((char const*,int)); -void *memcpy P((void*,void const*,size_t)); -#if has_memmove - void *memmove P((void*,void const*,size_t)); -#endif - -/* <time.h> */ -time_t time P((time_t*)); diff --git a/gnu/usr.bin/rcs/lib/maketime.c b/gnu/usr.bin/rcs/lib/maketime.c deleted file mode 100644 index 0f83bf5..0000000 --- a/gnu/usr.bin/rcs/lib/maketime.c +++ /dev/null @@ -1,344 +0,0 @@ -/* Convert struct partime into time_t. */ - -/* Copyright 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#if has_conf_h -# include "conf.h" -#else -# ifdef __STDC__ -# define P(x) x -# else -# define const -# define P(x) () -# endif -# include <stdlib.h> -# include <time.h> -#endif - -#include "partime.h" -#include "maketime.h" - -char const maketId[] - = "$FreeBSD$"; - -static int isleap P((int)); -static int month_days P((struct tm const*)); -static time_t maketime P((struct partime const*,time_t)); - -/* -* For maximum portability, use only localtime and gmtime. -* Make no assumptions about the time_t epoch or the range of time_t values. -* Avoid mktime because it's not universal and because there's no easy, -* portable way for mktime to yield the inverse of gmtime. -*/ - -#define TM_YEAR_ORIGIN 1900 - - static int -isleap(y) - int y; -{ - return (y&3) == 0 && (y%100 != 0 || y%400 == 0); -} - -static int const month_yday[] = { - /* days in year before start of months 0-12 */ - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 -}; - -/* Yield the number of days in TM's month. */ - static int -month_days(tm) - struct tm const *tm; -{ - int m = tm->tm_mon; - return month_yday[m+1] - month_yday[m] - + (m==1 && isleap(tm->tm_year + TM_YEAR_ORIGIN)); -} - -/* -* Convert UNIXTIME to struct tm form. -* Use gmtime if available and if !LOCALZONE, localtime otherwise. -*/ - struct tm * -time2tm(unixtime, localzone) - time_t unixtime; - int localzone; -{ - struct tm *tm; -# if TZ_must_be_set - static char const *TZ; - if (!TZ && !(TZ = getenv("TZ"))) - faterror("The TZ environment variable is not set; please set it to your timezone"); -# endif - if (localzone || !(tm = gmtime(&unixtime))) - tm = localtime(&unixtime); - return tm; -} - -/* Yield A - B, measured in seconds. */ - time_t -difftm(a, b) - struct tm const *a, *b; -{ - int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); - int by = b->tm_year + (TM_YEAR_ORIGIN - 1); - int difference_in_day_of_year = a->tm_yday - b->tm_yday; - int intervening_leap_days = ( - ((ay >> 2) - (by >> 2)) - - (ay/100 - by/100) - + ((ay/100 >> 2) - (by/100 >> 2)) - ); - time_t difference_in_years = ay - by; - time_t difference_in_days = ( - difference_in_years*365 - + (intervening_leap_days + difference_in_day_of_year) - ); - return - ( - ( - 24*difference_in_days - + (a->tm_hour - b->tm_hour) - )*60 + (a->tm_min - b->tm_min) - )*60 + (a->tm_sec - b->tm_sec); -} - -/* -* Adjust time T by adding SECONDS. SECONDS must be at most 24 hours' worth. -* Adjust only T's year, mon, mday, hour, min and sec members; -* plus adjust wday if it is defined. -*/ - void -adjzone(t, seconds) - register struct tm *t; - long seconds; -{ - /* - * This code can be off by a second if SECONDS is not a multiple of 60, - * if T is local time, and if a leap second happens during this minute. - * But this bug has never occurred, and most likely will not ever occur. - * Liberia, the last country for which SECONDS % 60 was nonzero, - * switched to UTC in May 1972; the first leap second was in June 1972. - */ - int leap_second = t->tm_sec == 60; - long sec = seconds + (t->tm_sec - leap_second); - if (sec < 0) { - if ((t->tm_min -= (59-sec)/60) < 0) { - if ((t->tm_hour -= (59-t->tm_min)/60) < 0) { - t->tm_hour += 24; - if (TM_DEFINED(t->tm_wday) && --t->tm_wday < 0) - t->tm_wday = 6; - if (--t->tm_mday <= 0) { - if (--t->tm_mon < 0) { - --t->tm_year; - t->tm_mon = 11; - } - t->tm_mday = month_days(t); - } - } - t->tm_min += 24 * 60; - } - sec += 24L * 60 * 60; - } else - if (60 <= (t->tm_min += sec/60)) - if (24 <= (t->tm_hour += t->tm_min/60)) { - t->tm_hour -= 24; - if (TM_DEFINED(t->tm_wday) && ++t->tm_wday == 7) - t->tm_wday = 0; - if (month_days(t) < ++t->tm_mday) { - if (11 < ++t->tm_mon) { - ++t->tm_year; - t->tm_mon = 0; - } - t->tm_mday = 1; - } - } - t->tm_min %= 60; - t->tm_sec = (int) (sec%60) + leap_second; -} - -/* -* Convert TM to time_t, using localtime if LOCALZONE and gmtime otherwise. -* Use only TM's year, mon, mday, hour, min, and sec members. -* Ignore TM's old tm_yday and tm_wday, but fill in their correct values. -* Yield -1 on failure (e.g. a member out of range). -* Posix 1003.1-1990 doesn't allow leap seconds, but some implementations -* have them anyway, so allow them if localtime/gmtime does. -*/ - time_t -tm2time(tm, localzone) - struct tm *tm; - int localzone; -{ - /* Cache the most recent t,tm pairs; 1 for gmtime, 1 for localtime. */ - static time_t t_cache[2]; - static struct tm tm_cache[2]; - - time_t d, gt; - struct tm const *gtm; - /* - * The maximum number of iterations should be enough to handle any - * combinations of leap seconds, time zone rule changes, and solar time. - * 4 is probably enough; we use a bigger number just to be safe. - */ - int remaining_tries = 8; - - /* Avoid subscript errors. */ - if (12 <= (unsigned)tm->tm_mon) - return -1; - - tm->tm_yday = month_yday[tm->tm_mon] + tm->tm_mday - - (tm->tm_mon<2 || ! isleap(tm->tm_year + TM_YEAR_ORIGIN)); - - /* Make a first guess. */ - gt = t_cache[localzone]; - gtm = gt ? &tm_cache[localzone] : time2tm(gt,localzone); - - /* Repeatedly use the error from the guess to improve the guess. */ - while ((d = difftm(tm, gtm)) != 0) { - if (--remaining_tries == 0) - return -1; - gt += d; - gtm = time2tm(gt,localzone); - } - t_cache[localzone] = gt; - tm_cache[localzone] = *gtm; - - /* - * Check that the guess actually matches; - * overflow can cause difftm to yield 0 even on differing times, - * or tm may have members out of range (e.g. bad leap seconds). - */ - if ( (tm->tm_year ^ gtm->tm_year) - | (tm->tm_mon ^ gtm->tm_mon) - | (tm->tm_mday ^ gtm->tm_mday) - | (tm->tm_hour ^ gtm->tm_hour) - | (tm->tm_min ^ gtm->tm_min) - | (tm->tm_sec ^ gtm->tm_sec)) - return -1; - - tm->tm_wday = gtm->tm_wday; - return gt; -} - -/* -* Check *PT and convert it to time_t. -* If it is incompletely specified, use DEFAULT_TIME to fill it out. -* Use localtime if PT->zone is the special value TM_LOCAL_ZONE. -* Yield -1 on failure. -* ISO 8601 day-of-year and week numbers are not yet supported. -*/ - static time_t -maketime(pt, default_time) - struct partime const *pt; - time_t default_time; -{ - int localzone, wday; - struct tm tm; - struct tm *tm0 = 0; - time_t r; - - tm0 = 0; /* Keep gcc -Wall happy. */ - localzone = pt->zone==TM_LOCAL_ZONE; - - tm = pt->tm; - - if (TM_DEFINED(pt->ymodulus) || !TM_DEFINED(tm.tm_year)) { - /* Get tm corresponding to current time. */ - tm0 = time2tm(default_time, localzone); - if (!localzone) - adjzone(tm0, pt->zone); - } - - if (TM_DEFINED(pt->ymodulus)) - tm.tm_year += - (tm0->tm_year + TM_YEAR_ORIGIN)/pt->ymodulus * pt->ymodulus; - else if (!TM_DEFINED(tm.tm_year)) { - /* Set default year, month, day from current time. */ - tm.tm_year = tm0->tm_year + TM_YEAR_ORIGIN; - if (!TM_DEFINED(tm.tm_mon)) { - tm.tm_mon = tm0->tm_mon; - if (!TM_DEFINED(tm.tm_mday)) - tm.tm_mday = tm0->tm_mday; - } - } - - /* Convert from partime year (Gregorian) to Posix year. */ - tm.tm_year -= TM_YEAR_ORIGIN; - - /* Set remaining default fields to be their minimum values. */ - if (!TM_DEFINED(tm.tm_mon)) tm.tm_mon = 0; - if (!TM_DEFINED(tm.tm_mday)) tm.tm_mday = 1; - if (!TM_DEFINED(tm.tm_hour)) tm.tm_hour = 0; - if (!TM_DEFINED(tm.tm_min)) tm.tm_min = 0; - if (!TM_DEFINED(tm.tm_sec)) tm.tm_sec = 0; - - if (!localzone) - adjzone(&tm, -pt->zone); - wday = tm.tm_wday; - - /* Convert and fill in the rest of the tm. */ - r = tm2time(&tm, localzone); - - /* Check weekday. */ - if (r != -1 && TM_DEFINED(wday) && wday != tm.tm_wday) - return -1; - - return r; -} - -/* Parse a free-format date in SOURCE, yielding a Unix format time. */ - time_t -str2time(source, default_time, default_zone) - char const *source; - time_t default_time; - long default_zone; -{ - struct partime pt; - - if (*partime(source, &pt)) - return -1; - if (pt.zone == TM_UNDEFINED_ZONE) - pt.zone = default_zone; - return maketime(&pt, default_time); -} - -#if TEST -#include <stdio.h> - int -main(argc, argv) int argc; char **argv; -{ - time_t default_time = time((time_t *)0); - long default_zone = argv[1] ? atol(argv[1]) : 0; - char buf[1000]; - while (fgets(buf, 1000, stdin)) { - time_t t = str2time(buf, default_time, default_zone); - printf("%s", asctime(gmtime(&t))); - } - return 0; -} -#endif diff --git a/gnu/usr.bin/rcs/lib/maketime.h b/gnu/usr.bin/rcs/lib/maketime.h deleted file mode 100644 index fbe1256..0000000 --- a/gnu/usr.bin/rcs/lib/maketime.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Yield time_t from struct partime yielded by partime. */ - -/* Copyright 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#if defined(__STDC__) || has_prototypes -# define __MAKETIME_P(x) x -#else -# define __MAKETIME_P(x) () -#endif - -struct tm *time2tm __MAKETIME_P((time_t,int)); -time_t difftm __MAKETIME_P((struct tm const *, struct tm const *)); -time_t str2time __MAKETIME_P((char const *, time_t, long)); -time_t tm2time __MAKETIME_P((struct tm *, int)); -void adjzone __MAKETIME_P((struct tm *, long)); diff --git a/gnu/usr.bin/rcs/lib/merger.c b/gnu/usr.bin/rcs/lib/merger.c deleted file mode 100644 index 8f1d610..0000000 --- a/gnu/usr.bin/rcs/lib/merger.c +++ /dev/null @@ -1,148 +0,0 @@ -/* three-way file merge internals */ - -/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#include "rcsbase.h" - -libId(mergerId, "$FreeBSD$") - - static char const *normalize_arg P((char const*,char**)); - static char const * -normalize_arg(s, b) - char const *s; - char **b; -/* - * If S looks like an option, prepend ./ to it. Yield the result. - * Set *B to the address of any storage that was allocated. - */ -{ - char *t; - if (*s == '-') { - *b = t = testalloc(strlen(s) + 3); - VOID sprintf(t, ".%c%s", SLASH, s); - return t; - } else { - *b = 0; - return s; - } -} - - int -merge(tostdout, edarg, label, argv) - int tostdout; - char const *edarg; - char const *const label[3]; - char const *const argv[3]; -/* - * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2', - * where TOSTDOUT specifies whether -p is present, - * EDARG gives the editing type (e.g. "-A", or null for the default), - * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2. - * Yield DIFF_SUCCESS or DIFF_FAILURE. - */ -{ - register int i; - FILE *f; - RILE *rt; - char const *a[3], *t; - char *b[3]; - int s; -#if !DIFF3_BIN - char const *d[2]; -#endif - - for (i=3; 0<=--i; ) - a[i] = normalize_arg(argv[i], &b[i]); - - if (!edarg) - edarg = "-E"; - -#if DIFF3_BIN - t = 0; - if (!tostdout) - t = maketemp(0); - s = run( - -1, t, - DIFF3, edarg, "-am", - "-L", label[0], - "-L", label[1], - "-L", label[2], - a[0], a[1], a[2], (char*)0 - ); - switch (s) { - case DIFF_SUCCESS: - break; - case DIFF_FAILURE: - warn("conflicts during merge"); - break; - default: - exiterr(); - } - if (t) { - if (!(f = fopenSafer(argv[0], "w"))) - efaterror(argv[0]); - if (!(rt = Iopen(t, "r", (struct stat*)0))) - efaterror(t); - fastcopy(rt, f); - Ifclose(rt); - Ofclose(f); - } -#else - for (i=0; i<2; i++) - switch (run( - -1, d[i]=maketemp(i), - DIFF, a[i], a[2], (char*)0 - )) { - case DIFF_FAILURE: case DIFF_SUCCESS: break; - default: faterror("diff failed"); - } - t = maketemp(2); - s = run( - -1, t, - DIFF3, edarg, d[0], d[1], a[0], a[1], a[2], - label[0], label[2], (char*)0 - ); - if (s != DIFF_SUCCESS) { - s = DIFF_FAILURE; - warn("overlaps or other problems during merge"); - } - if (!(f = fopenSafer(t, "a+"))) - efaterror(t); - aputs(tostdout ? "1,$p\n" : "w\n", f); - Orewind(f); - aflush(f); - if (run(fileno(f), (char*)0, ED, "-", a[0], (char*)0)) - exiterr(); - Ofclose(f); -#endif - - tempunlink(); - for (i=3; 0<=--i; ) - if (b[i]) - tfree(b[i]); - return s; -} diff --git a/gnu/usr.bin/rcs/lib/partime.c b/gnu/usr.bin/rcs/lib/partime.c deleted file mode 100644 index 05b0108..0000000 --- a/gnu/usr.bin/rcs/lib/partime.c +++ /dev/null @@ -1,701 +0,0 @@ -/* Parse a string, yielding a struct partime that describes it. */ - -/* Copyright 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#if has_conf_h -# include "conf.h" -#else -# ifdef __STDC__ -# define P(x) x -# else -# define const -# define P(x) () -# endif -# include <limits.h> -# include <time.h> -#endif - -#include <ctype.h> -#undef isdigit -#define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than stock */ - -#include "partime.h" - -char const partimeId[] - = "$FreeBSD$"; - - -/* Lookup tables for names of months, weekdays, time zones. */ - -#define NAME_LENGTH_MAXIMUM 4 - -struct name_val { - char name[NAME_LENGTH_MAXIMUM]; - int val; -}; - - -static char const *parse_decimal P((char const*,int,int,int,int,int*,int*)); -static char const *parse_fixed P((char const*,int,int*)); -static char const *parse_pattern_letter P((char const*,int,struct partime*)); -static char const *parse_prefix P((char const*,struct partime*,int*)); -static char const *parse_ranged P((char const*,int,int,int,int*)); -static int lookup P((char const*,struct name_val const[])); -static int merge_partime P((struct partime*, struct partime const*)); -static void undefine P((struct partime*)); - - -static struct name_val const month_names[] = { - {"jan",0}, {"feb",1}, {"mar",2}, {"apr",3}, {"may",4}, {"jun",5}, - {"jul",6}, {"aug",7}, {"sep",8}, {"oct",9}, {"nov",10}, {"dec",11}, - {"", TM_UNDEFINED} -}; - -static struct name_val const weekday_names[] = { - {"sun",0}, {"mon",1}, {"tue",2}, {"wed",3}, {"thu",4}, {"fri",5}, {"sat",6}, - {"", TM_UNDEFINED} -}; - -#define hr60nonnegative(t) ((t)/100 * 60 + (t)%100) -#define hr60(t) ((t)<0 ? -hr60nonnegative(-(t)) : hr60nonnegative(t)) -#define zs(t,s) {s, hr60(t)} -#define zd(t,s,d) zs(t, s), zs((t)+100, d) - -static struct name_val const zone_names[] = { - zs(-1000, "hst"), /* Hawaii */ - zd(-1000,"hast","hadt"),/* Hawaii-Aleutian */ - zd(- 900,"akst","akdt"),/* Alaska */ - zd(- 800, "pst", "pdt"),/* Pacific */ - zd(- 700, "mst", "mdt"),/* Mountain */ - zd(- 600, "cst", "cdt"),/* Central */ - zd(- 500, "est", "edt"),/* Eastern */ - zd(- 400, "ast", "adt"),/* Atlantic */ - zd(- 330, "nst", "ndt"),/* Newfoundland */ - zs( 000, "utc"), /* Coordinated Universal */ - zs( 000, "cut"), /* " */ - zs( 000, "ut"), /* Universal */ - zs( 000, "z"), /* Zulu (required by ISO 8601) */ - zd( 000, "gmt", "bst"),/* Greenwich Mean, British Summer */ - zs( 000, "wet"), /* Western Europe */ - zs( 100, "met"), /* Middle Europe */ - zs( 100, "cet"), /* Central Europe */ - zs( 200, "eet"), /* Eastern Europe */ - zs( 530, "ist"), /* India */ - zd( 900, "jst", "jdt"),/* Japan */ - zd( 900, "kst", "kdt"),/* Korea */ - zd( 1200,"nzst","nzdt"),/* New Zealand */ - { "lt", 1 }, -#if 0 - /* The following names are duplicates or are not well attested. */ - zs(-1100, "sst"), /* Samoa */ - zs(-1000, "tht"), /* Tahiti */ - zs(- 930, "mqt"), /* Marquesas */ - zs(- 900, "gbt"), /* Gambier */ - zd(- 900, "yst", "ydt"),/* Yukon - name is no longer used */ - zs(- 830, "pit"), /* Pitcairn */ - zd(- 500, "cst", "cdt"),/* Cuba */ - zd(- 500, "ast", "adt"),/* Acre */ - zd(- 400, "wst", "wdt"),/* Western Brazil */ - zd(- 400, "ast", "adt"),/* Andes */ - zd(- 400, "cst", "cdt"),/* Chile */ - zs(- 300, "wgt"), /* Western Greenland */ - zd(- 300, "est", "edt"),/* Eastern South America */ - zs(- 300, "mgt"), /* Middle Greenland */ - zd(- 200, "fst", "fdt"),/* Fernando de Noronha */ - zs(- 100, "egt"), /* Eastern Greenland */ - zs(- 100, "aat"), /* Atlantic Africa */ - zs(- 100, "act"), /* Azores and Canaries */ - zs( 000, "wat"), /* West Africa */ - zs( 100, "cat"), /* Central Africa */ - zd( 100, "mez","mesz"),/* Mittel-Europaeische Zeit */ - zs( 200, "sat"), /* South Africa */ - zd( 200, "ist", "idt"),/* Israel */ - zs( 300, "eat"), /* East Africa */ - zd( 300, "ast", "adt"),/* Arabia */ - zd( 300, "msk", "msd"),/* Moscow */ - zd( 330, "ist", "idt"),/* Iran */ - zs( 400, "gst"), /* Gulf */ - zs( 400, "smt"), /* Seychelles & Mascarene */ - zd( 400, "esk", "esd"),/* Yekaterinburg */ - zd( 400, "bsk", "bsd"),/* Baku */ - zs( 430, "aft"), /* Afghanistan */ - zd( 500, "osk", "osd"),/* Omsk */ - zs( 500, "pkt"), /* Pakistan */ - zd( 500, "tsk", "tsd"),/* Tashkent */ - zs( 545, "npt"), /* Nepal */ - zs( 600, "bgt"), /* Bangladesh */ - zd( 600, "nsk", "nsd"),/* Novosibirsk */ - zs( 630, "bmt"), /* Burma */ - zs( 630, "cct"), /* Cocos */ - zs( 700, "ict"), /* Indochina */ - zs( 700, "jvt"), /* Java */ - zd( 700, "isk", "isd"),/* Irkutsk */ - zs( 800, "hkt"), /* Hong Kong */ - zs( 800, "pst"), /* Philippines */ - zs( 800, "sgt"), /* Singapore */ - zd( 800, "cst", "cdt"),/* China */ - zd( 800, "ust", "udt"),/* Ulan Bator */ - zd( 800, "wst", "wst"),/* Western Australia */ - zd( 800, "ysk", "ysd"),/* Yakutsk */ - zs( 900, "blt"), /* Belau */ - zs( 900, "mlt"), /* Moluccas */ - zd( 900, "vsk", "vsd"),/* Vladivostok */ - zd( 930, "cst", "cst"),/* Central Australia */ - zs( 1000, "gst"), /* Guam */ - zd( 1000, "gsk", "gsd"),/* Magadan */ - zd( 1000, "est", "est"),/* Eastern Australia */ - zd( 1100,"lhst","lhst"),/* Lord Howe */ - zd( 1100, "psk", "psd"),/* Petropavlovsk-Kamchatski */ - zs( 1100,"ncst"), /* New Caledonia */ - zs( 1130,"nrft"), /* Norfolk */ - zd( 1200, "ask", "asd"),/* Anadyr */ - zs( 1245,"nz-chat"), /* Chatham */ - zs( 1300, "tgt"), /* Tongatapu */ -#endif - {"", -1} -}; - - static int -lookup (s, table) - char const *s; - struct name_val const table[]; -/* Look for a prefix of S in TABLE, returning val for first matching entry. */ -{ - int j; - char buf[NAME_LENGTH_MAXIMUM]; - - for (j = 0; j < NAME_LENGTH_MAXIMUM; j++) { - unsigned char c = *s++; - buf[j] = isupper (c) ? tolower (c) : c; - if (!isalpha (c)) - break; - } - for (; table[0].name[0]; table++) - for (j = 0; buf[j] == table[0].name[j]; ) - if (++j == NAME_LENGTH_MAXIMUM || !table[0].name[j]) - goto done; - done: - return table[0].val; -} - - - static void -undefine (t) struct partime *t; -/* Set *T to ``undefined'' values. */ -{ - t->tm.tm_sec = t->tm.tm_min = t->tm.tm_hour = t->tm.tm_mday = t->tm.tm_mon - = t->tm.tm_year = t->tm.tm_wday = t->tm.tm_yday - = t->ymodulus = t->yweek - = TM_UNDEFINED; - t->zone = TM_UNDEFINED_ZONE; -} - -/* -* Array of patterns to look for in a date string. -* Order is important: we look for the first matching pattern -* whose values do not contradict values that we already know about. -* See `parse_pattern_letter' below for the meaning of the pattern codes. -*/ -static char const * const patterns[] = { - /* - * These traditional patterns must come first, - * to prevent an ISO 8601 format from misinterpreting their prefixes. - */ - "E_n_y", "x", /* RFC 822 */ - "E_n", "n_E", "n", "t:m:s_A", "t:m_A", "t_A", /* traditional */ - "y/N/D$", /* traditional RCS */ - - /* ISO 8601:1988 formats, generalized a bit. */ - "y-N-D$", "4ND$", "Y-N$", - "RND$", "-R=N$", "-R$", "--N=D$", "N=DT", - "--N$", "---D$", "DT", - "Y-d$", "4d$", "R=d$", "-d$", "dT", - "y-W-X", "yWX", "y=W", - "-r-W-X", "r-W-XT", "-rWX", "rWXT", "-W=X", "W=XT", "-W", - "-w-X", "w-XT", "---X$", "XT", "4$", - "T", - "h:m:s$", "hms$", "h:m$", "hm$", "h$", "-m:s$", "-ms$", "-m$", "--s$", - "Y", "Z", - - 0 -}; - - static char const * -parse_prefix (str, t, pi) char const *str; struct partime *t; int *pi; -/* -* Parse an initial prefix of STR, setting *T accordingly. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -* Start with pattern *PI; if success, set *PI to the next pattern to try. -* Set *PI to -1 if we know there are no more patterns to try; -* if *PI is initially negative, give up immediately. -*/ -{ - int i = *pi; - char const *pat; - unsigned char c; - - if (i < 0) - return 0; - - /* Remove initial noise. */ - while (!isalnum (c = *str) && c != '-' && c != '+') { - if (!c) { - undefine (t); - *pi = -1; - return str; - } - str++; - } - - /* Try a pattern until one succeeds. */ - while ((pat = patterns[i++]) != 0) { - char const *s = str; - undefine (t); - do { - if (!(c = *pat++)) { - *pi = i; - return s; - } - } while ((s = parse_pattern_letter (s, c, t)) != 0); - } - - return 0; -} - - static char const * -parse_fixed (s, digits, res) char const *s; int digits, *res; -/* -* Parse an initial prefix of S of length DIGITS; it must be a number. -* Store the parsed number into *RES. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - int n = 0; - char const *lim = s + digits; - while (s < lim) { - unsigned d = *s++ - '0'; - if (9 < d) - return 0; - n = 10*n + d; - } - *res = n; - return s; -} - - static char const * -parse_ranged (s, digits, lo, hi, res) char const *s; int digits, lo, hi, *res; -/* -* Parse an initial prefix of S of length DIGITS; -* it must be a number in the range LO through HI. -* Store the parsed number into *RES. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - s = parse_fixed (s, digits, res); - return s && lo<=*res && *res<=hi ? s : 0; -} - - static char const * -parse_decimal (s, digits, lo, hi, resolution, res, fres) - char const *s; - int digits, lo, hi, resolution, *res, *fres; -/* -* Parse an initial prefix of S of length DIGITS; -* it must be a number in the range LO through HI -* and it may be followed by a fraction that is to be computed using RESOLUTION. -* Store the parsed number into *RES; store the fraction times RESOLUTION, -* rounded to the nearest integer, into *FRES. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - s = parse_fixed (s, digits, res); - if (s && lo<=*res && *res<=hi) { - int f = 0; - if ((s[0]==',' || s[0]=='.') && isdigit ((unsigned char) s[1])) { - char const *s1 = ++s; - int num10 = 0, denom10 = 10, product; - while (isdigit ((unsigned char) *++s)) - denom10 *= 10; - s = parse_fixed (s1, s - s1, &num10); - product = num10*resolution; - f = (product + (denom10>>1)) / denom10; - f -= f & (product%denom10 == denom10>>1); /* round to even */ - if (f < 0 || product/resolution != num10) - return 0; /* overflow */ - } - *fres = f; - return s; - } - return 0; -} - - char * -parzone (s, zone) char const *s; long *zone; -/* -* Parse an initial prefix of S; it must denote a time zone. -* Set *ZONE to the number of seconds east of GMT, -* or to TM_LOCAL_ZONE if it is the local time zone. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - char sign; - int hh, mm, ss; - int minutesEastOfUTC; - long offset, z; - - /* - * The formats are LT, n, n DST, nDST, no, o - * where n is a time zone name - * and o is a time zone offset of the form [-+]hh[:mm[:ss]]. - */ - switch (*s) { - case '-': case '+': - z = 0; - break; - - default: - minutesEastOfUTC = lookup (s, zone_names); - if (minutesEastOfUTC == -1) - return 0; - - /* Don't bother to check rest of spelling. */ - while (isalpha ((unsigned char) *s)) - s++; - - /* Don't modify LT. */ - if (minutesEastOfUTC == 1) { - *zone = TM_LOCAL_ZONE; - return (char *) s; - } - - z = minutesEastOfUTC * 60L; - - /* Look for trailing " DST". */ - if ( - (s[-1]=='T' || s[-1]=='t') && - (s[-2]=='S' || s[-2]=='s') && - (s[-3]=='D' || s[-3]=='t') - ) - goto trailing_dst; - while (isspace ((unsigned char) *s)) - s++; - if ( - (s[0]=='D' || s[0]=='d') && - (s[1]=='S' || s[1]=='s') && - (s[2]=='T' || s[2]=='t') - ) { - s += 3; - trailing_dst: - *zone = z + 60*60; - return (char *) s; - } - - switch (*s) { - case '-': case '+': break; - default: return (char *) s; - } - } - sign = *s++; - - if (!(s = parse_ranged (s, 2, 0, 23, &hh))) - return 0; - mm = ss = 0; - if (*s == ':') - s++; - if (isdigit ((unsigned char) *s)) { - if (!(s = parse_ranged (s, 2, 0, 59, &mm))) - return 0; - if (*s==':' && s[-3]==':' && isdigit ((unsigned char) s[1])) { - if (!(s = parse_ranged (s + 1, 2, 0, 59, &ss))) - return 0; - } - } - if (isdigit ((unsigned char) *s)) - return 0; - offset = (hh*60 + mm)*60L + ss; - *zone = z + (sign=='-' ? -offset : offset); - /* - * ?? Are fractions allowed here? - * If so, they're not implemented. - */ - return (char *) s; -} - - static char const * -parse_pattern_letter (s, c, t) char const *s; int c; struct partime *t; -/* -* Parse an initial prefix of S, matching the pattern whose code is C. -* Set *T accordingly. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - switch (c) { - case '$': /* The next character must be a non-digit. */ - if (isdigit ((unsigned char) *s)) - return 0; - break; - - case '-': case '/': case ':': - /* These characters stand for themselves. */ - if (*s++ != c) - return 0; - break; - - case '4': /* 4-digit year */ - s = parse_fixed (s, 4, &t->tm.tm_year); - break; - - case '=': /* optional '-' */ - s += *s == '-'; - break; - - case 'A': /* AM or PM */ - /* - * This matches the regular expression [AaPp][Mm]?. - * It must not be followed by a letter or digit; - * otherwise it would match prefixes of strings like "PST". - */ - switch (*s++) { - case 'A': case 'a': - if (t->tm.tm_hour == 12) - t->tm.tm_hour = 0; - break; - - case 'P': case 'p': - if (t->tm.tm_hour != 12) - t->tm.tm_hour += 12; - break; - - default: return 0; - } - switch (*s) { - case 'M': case 'm': s++; break; - } - if (isalnum (*s)) - return 0; - break; - - case 'D': /* day of month [01-31] */ - s = parse_ranged (s, 2, 1, 31, &t->tm.tm_mday); - break; - - case 'd': /* day of year [001-366] */ - s = parse_ranged (s, 3, 1, 366, &t->tm.tm_yday); - t->tm.tm_yday--; - break; - - case 'E': /* extended day of month [1-9, 01-31] */ - s = parse_ranged (s, ( - isdigit ((unsigned char) s[0]) && - isdigit ((unsigned char) s[1]) - ) + 1, 1, 31, &t->tm.tm_mday); - break; - - case 'h': /* hour [00-23 followed by optional fraction] */ - { - int frac; - s = parse_decimal (s, 2, 0, 23, 60*60, &t->tm.tm_hour, &frac); - t->tm.tm_min = frac / 60; - t->tm.tm_sec = frac % 60; - } - break; - - case 'm': /* minute [00-59 followed by optional fraction] */ - s = parse_decimal (s, 2, 0, 59, 60, &t->tm.tm_min, &t->tm.tm_sec); - break; - - case 'n': /* month name [e.g. "Jan"] */ - if (!TM_DEFINED (t->tm.tm_mon = lookup (s, month_names))) - return 0; - /* Don't bother to check rest of spelling. */ - while (isalpha ((unsigned char) *s)) - s++; - break; - - case 'N': /* month [01-12] */ - s = parse_ranged (s, 2, 1, 12, &t->tm.tm_mon); - t->tm.tm_mon--; - break; - - case 'r': /* year % 10 (remainder in origin-0 decade) [0-9] */ - s = parse_fixed (s, 1, &t->tm.tm_year); - t->ymodulus = 10; - break; - - case_R: - case 'R': /* year % 100 (remainder in origin-0 century) [00-99] */ - s = parse_fixed (s, 2, &t->tm.tm_year); - t->ymodulus = 100; - break; - - case 's': /* second [00-60 followed by optional fraction] */ - { - int frac; - s = parse_decimal (s, 2, 0, 60, 1, &t->tm.tm_sec, &frac); - t->tm.tm_sec += frac; - } - break; - - case 'T': /* 'T' or 't' */ - switch (*s++) { - case 'T': case 't': break; - default: return 0; - } - break; - - case 't': /* traditional hour [1-9 or 01-12] */ - s = parse_ranged (s, ( - isdigit ((unsigned char) s[0]) && isdigit ((unsigned char) s[1]) - ) + 1, 1, 12, &t->tm.tm_hour); - break; - - case 'w': /* 'W' or 'w' only (stands for current week) */ - switch (*s++) { - case 'W': case 'w': break; - default: return 0; - } - break; - - case 'W': /* 'W' or 'w', followed by a week of year [00-53] */ - switch (*s++) { - case 'W': case 'w': break; - default: return 0; - } - s = parse_ranged (s, 2, 0, 53, &t->yweek); - break; - - case 'X': /* weekday (1=Mon ... 7=Sun) [1-7] */ - s = parse_ranged (s, 1, 1, 7, &t->tm.tm_wday); - t->tm.tm_wday--; - break; - - case 'x': /* weekday name [e.g. "Sun"] */ - if (!TM_DEFINED (t->tm.tm_wday = lookup (s, weekday_names))) - return 0; - /* Don't bother to check rest of spelling. */ - while (isalpha ((unsigned char) *s)) - s++; - break; - - case 'y': /* either R or Y */ - if ( - isdigit ((unsigned char) s[0]) && - isdigit ((unsigned char) s[1]) && - !isdigit ((unsigned char) s[2]) - ) - goto case_R; - /* fall into */ - case 'Y': /* year in full [4 or more digits] */ - { - int len = 0; - while (isdigit ((unsigned char) s[len])) - len++; - if (len < 4) - return 0; - s = parse_fixed (s, len, &t->tm.tm_year); - } - break; - - case 'Z': /* time zone */ - s = parzone (s, &t->zone); - break; - - case '_': /* possibly empty sequence of non-alphanumerics */ - while (!isalnum (*s) && *s) - s++; - break; - - default: /* bad pattern */ - return 0; - } - return s; -} - - static int -merge_partime (t, u) struct partime *t; struct partime const *u; -/* -* If there is no conflict, merge into *T the additional information in *U -* and return 0. Otherwise do nothing and return -1. -*/ -{ -# define conflict(a,b) ((a) != (b) && TM_DEFINED (a) && TM_DEFINED (b)) - if ( - conflict (t->tm.tm_sec, u->tm.tm_sec) || - conflict (t->tm.tm_min, u->tm.tm_min) || - conflict (t->tm.tm_hour, u->tm.tm_hour) || - conflict (t->tm.tm_mday, u->tm.tm_mday) || - conflict (t->tm.tm_mon, u->tm.tm_mon) || - conflict (t->tm.tm_year, u->tm.tm_year) || - conflict (t->tm.tm_wday, u->tm.tm_yday) || - conflict (t->ymodulus, u->ymodulus) || - conflict (t->yweek, u->yweek) || - ( - t->zone != u->zone && - t->zone != TM_UNDEFINED_ZONE && - u->zone != TM_UNDEFINED_ZONE - ) - ) - return -1; -# undef conflict -# define merge_(a,b) if (TM_DEFINED (b)) (a) = (b); - merge_ (t->tm.tm_sec, u->tm.tm_sec) - merge_ (t->tm.tm_min, u->tm.tm_min) - merge_ (t->tm.tm_hour, u->tm.tm_hour) - merge_ (t->tm.tm_mday, u->tm.tm_mday) - merge_ (t->tm.tm_mon, u->tm.tm_mon) - merge_ (t->tm.tm_year, u->tm.tm_year) - merge_ (t->tm.tm_wday, u->tm.tm_yday) - merge_ (t->ymodulus, u->ymodulus) - merge_ (t->yweek, u->yweek) -# undef merge_ - if (u->zone != TM_UNDEFINED_ZONE) t->zone = u->zone; - return 0; -} - - char * -partime (s, t) char const *s; struct partime *t; -/* -* Parse a date/time prefix of S, putting the parsed result into *T. -* Return the first character after the prefix. -* The prefix may contain no useful information; -* in that case, *T will contain only undefined values. -*/ -{ - struct partime p; - - undefine (t); - while (*s) { - int i = 0; - char const *s1; - do { - if (!(s1 = parse_prefix (s, &p, &i))) - return (char *) s; - } while (merge_partime (t, &p) != 0); - s = s1; - } - return (char *) s; -} diff --git a/gnu/usr.bin/rcs/lib/partime.h b/gnu/usr.bin/rcs/lib/partime.h deleted file mode 100644 index 5d3983f..0000000 --- a/gnu/usr.bin/rcs/lib/partime.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Parse a string, yielding a struct partime that describes it. */ - -/* Copyright 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#define TM_UNDEFINED (-1) -#define TM_DEFINED(x) (0 <= (x)) - -#define TM_UNDEFINED_ZONE ((long) -24 * 60 * 60) -#define TM_LOCAL_ZONE (TM_UNDEFINED_ZONE - 1) - -struct partime { - /* - * This structure describes the parsed time. - * Only the following tm_* values in it are used: - * sec, min, hour, mday, mon, year, wday, yday. - * If TM_UNDEFINED(value), the parser never found the value. - * The tm_year field is the actual year, not the year - 1900; - * but see ymodulus below. - */ - struct tm tm; - - /* - * If !TM_UNDEFINED(ymodulus), - * then tm.tm_year is actually modulo ymodulus. - */ - int ymodulus; - - /* - * Week of year, ISO 8601 style. - * If TM_UNDEFINED(yweek), the parser never found yweek. - * Weeks start on Mondays. - * Week 1 includes Jan 4. - */ - int yweek; - - /* Seconds east of UTC; or TM_LOCAL_ZONE or TM_UNDEFINED_ZONE. */ - long zone; -}; - -#if defined(__STDC__) || has_prototypes -# define __PARTIME_P(x) x -#else -# define __PARTIME_P(x) () -#endif - -char *partime __PARTIME_P((char const *, struct partime *)); -char *parzone __PARTIME_P((char const *, long *)); diff --git a/gnu/usr.bin/rcs/lib/rcsbase.h b/gnu/usr.bin/rcs/lib/rcsbase.h deleted file mode 100644 index 9f2f68c..0000000 --- a/gnu/usr.bin/rcs/lib/rcsbase.h +++ /dev/null @@ -1,762 +0,0 @@ -/* RCS common definitions and data structures */ - -#define RCSBASE "$FreeBSD$" - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.20 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.19 1995/06/01 16:23:43 eggert - * (SIZEABLE_PATH): Don't depend on PATH_MAX: it's not worth configuring. - * (Ioffset_type,BINARY_EXPAND,MIN_UNEXPAND,MIN_UNCHANGED_EXPAND): New macros. - * (maps_memory): New macro; replaces many instances of `has_mmap'. - * (cacheptr): Renamed from cachetell. - * (struct RILE): New alternate name for RILE; the type is now recursive. - * (deallocate): New member for RILE, used for generic buffer deallocation. - * (cacheunget_): No longer take a failure arg; just call Ierror on failure. - * (struct rcslock): Renamed from struct lock, to avoid collisions with - * system headers on some hosts. All users changed. - * (basefilename): Renamed from basename, likewise. - * (dirtpname): Remove; no longer external. - * (dirlen, dateform): Remove; no longer used. - * (cmpdate, fopenSafer, fdSafer, readAccessFilenameBuffer): New functions. - * (zonelenmax): Increase to 9 for full ISO 8601 format. - * (catchmmapints): Depend on has_NFS. - * - * Revision 5.18 1994/03/17 14:05:48 eggert - * Add primitives for reading backwards from a RILE; - * this is needed to go back and find the $Log prefix. - * Specify subprocess input via file descriptor, not file name. Remove lint. - * - * Revision 5.17 1993/11/09 17:40:15 eggert - * Move RCS-specific time handling into rcstime.c. - * printf_string now takes two arguments, alas. - * - * Revision 5.16 1993/11/03 17:42:27 eggert - * Don't arbitrarily limit the number of joins. Remove `nil'. - * Add Name keyword. Don't discard ignored phrases. - * Add support for merge -A vs -E, and allow up to three labels. - * Improve quality of diagnostics and prototypes. - * - * Revision 5.15 1992/07/28 16:12:44 eggert - * Statement macro names now end in _. - * - * Revision 5.14 1992/02/17 23:02:22 eggert - * Add -T support. Work around NFS mmap SIGBUS problem. - * - * Revision 5.13 1992/01/24 18:44:19 eggert - * Add support for bad_creat0. lint -> RCS_lint - * - * Revision 5.12 1992/01/06 02:42:34 eggert - * while (E) ; -> while (E) continue; - * - * Revision 5.11 1991/10/07 17:32:46 eggert - * Support piece tables even if !has_mmap. - * - * Revision 5.10 1991/09/24 00:28:39 eggert - * Remove unexported functions. - * - * Revision 5.9 1991/08/19 03:13:55 eggert - * Add piece tables and other tuneups, and NFS workarounds. - * - * Revision 5.8 1991/04/21 11:58:20 eggert - * Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.7 1991/02/28 19:18:50 eggert - * Try setuid() if seteuid() doesn't work. - * - * Revision 5.6 1991/02/26 17:48:37 eggert - * Support new link behavior. Move ANSI C / Posix declarations into conf.sh. - * - * Revision 5.5 1990/12/04 05:18:43 eggert - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.4 1990/11/01 05:03:35 eggert - * Don't assume that builtins are functions; they may be macros. - * Permit arbitrary data in logs. - * - * Revision 5.3 1990/09/26 23:36:58 eggert - * Port wait() to non-Posix ANSI C hosts. - * - * Revision 5.2 1990/09/04 08:02:20 eggert - * Don't redefine NAME_MAX, PATH_MAX. - * Improve incomplete line handling. Standardize yes-or-no procedure. - * - * Revision 5.1 1990/08/29 07:13:53 eggert - * Add -kkvl. Fix type typos exposed by porting. Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:12:44 eggert - * Adjust ANSI C / Posix support. Add -k, -V, setuid. Don't call access(). - * Remove compile-time limits; use malloc instead. - * Ansify and Posixate. Add support for ISO 8859. - * Remove snoop and v2 support. - * - * Revision 4.9 89/05/01 15:17:14 narten - * botched previous USG fix - * - * Revision 4.8 89/05/01 14:53:05 narten - * changed #include <strings.h> -> string.h for USG systems. - * - * Revision 4.7 88/11/08 15:58:45 narten - * removed defs for functions loaded from libraries - * - * Revision 4.6 88/08/09 19:12:36 eggert - * Shrink stdio code size; remove lint; permit -Dhshsize=nn. - * - * Revision 4.5 87/12/18 17:06:41 narten - * made removed BSD ifdef, now uses V4_2BSD - * - * Revision 4.4 87/10/18 10:29:49 narten - * Updating version numbers - * Changes relative to 1.1 are actually relative to 4.2 - * - * Revision 1.3 87/09/24 14:02:25 narten - * changes for lint - * - * Revision 1.2 87/03/27 14:22:02 jenkins - * Port to suns - * - * Revision 4.2 83/12/20 16:04:20 wft - * merged 3.6.1.1 and 4.1 (SMALLOG, logsize). - * moved setting of STRICT_LOCKING to Makefile. - * changed DOLLAR to UNKN (conflict with KDELIM). - * - * Revision 4.1 83/05/04 09:12:41 wft - * Added markers Id and RCSfile. - * Added Dbranch for default branches. - * - * Revision 3.6.1.1 83/12/02 21:56:22 wft - * Increased logsize, added macro SMALLOG. - * - * Revision 3.6 83/01/15 16:43:28 wft - * 4.2 prerelease - * - * Revision 3.6 83/01/15 16:43:28 wft - * Replaced dbm.h with BYTESIZ, fixed definition of rindex(). - * Added variants of NCPFN and NCPPN for bsd 4.2, selected by defining V4_2BSD. - * Added macro DELNUMFORM to have uniform format for printing delta text nodes. - * Added macro DELETE to mark deleted deltas. - * - * Revision 3.5 82/12/10 12:16:56 wft - * Added two forms of DATEFORM, one using %02d, the other %.2d. - * - * Revision 3.4 82/12/04 20:01:25 wft - * added LOCKER, Locker, and USG (redefinition of rindex). - * - * Revision 3.3 82/12/03 12:22:04 wft - * Added dbm.h, stdio.h, RCSBASE, RCSSEP, RCSSUF, WORKMODE, TMPFILE3, - * PRINTDATE, PRINTTIME, map, and ctab; removed Suffix. Redefined keyvallength - * using NCPPN. Changed putc() to abort on write error. - * - * Revision 3.2 82/10/18 15:03:52 wft - * added macro STRICT_LOCKING, removed RCSUMASK. - * renamed JOINFILE[1,2] to JOINFIL[1,2]. - * - * Revision 3.1 82/10/11 19:41:17 wft - * removed NBPW, NBPC, NCPW. - * added typdef int void to aid compiling - */ - - -#include "conf.h" - - -#define EXIT_TROUBLE DIFF_TROUBLE - -#ifdef _POSIX_PATH_MAX -# define SIZEABLE_PATH _POSIX_PATH_MAX -#else -# define SIZEABLE_PATH 255 /* size of a large path; not a hard limit */ -#endif - -/* for traditional C hosts with unusual size arguments */ -#define Fread(p,s,n,f) fread(p, (freadarg_type)(s), (freadarg_type)(n), f) -#define Fwrite(p,s,n,f) fwrite(p, (freadarg_type)(s), (freadarg_type)(n), f) - - -/* - * Parameters - */ - -/* backwards compatibility with old versions of RCS */ -#define VERSION_min 3 /* old output RCS format supported */ -#define VERSION_max 5 /* newest output RCS format supported */ -#ifndef VERSION_DEFAULT /* default RCS output format */ -# define VERSION_DEFAULT VERSION_max -#endif -#define VERSION(n) ((n) - VERSION_DEFAULT) /* internally, 0 is the default */ - -#ifndef STRICT_LOCKING -#define STRICT_LOCKING 1 -#endif - /* 0 sets the default locking to non-strict; */ - /* used in experimental environments. */ - /* 1 sets the default locking to strict; */ - /* used in production environments. */ - -#define yearlength 16 /* (good through AD 9,999,999,999,999,999) */ -#define datesize (yearlength+16) /* size of output of time2date */ -#define RCSTMPPREFIX '_' /* prefix for temp files in working dir */ -#define KDELIM '$' /* delimiter for keywords */ -#define VDELIM ':' /* separates keywords from values */ -#define DEFAULTSTATE "Exp" /* default state of revisions */ - - - -#define true 1 -#define false 0 - - -/* - * RILE - readonly file - * declarecache; - declares local cache for RILE variable(s) - * setupcache - sets up the local RILE cache, but does not initialize it - * cache, uncache - caches and uncaches the local RILE; - * (uncache,cache) is needed around functions that advance the RILE pointer - * Igeteof_(f,c,s) - get a char c from f, executing statement s at EOF - * cachegeteof_(c,s) - Igeteof_ applied to the local RILE - * Iget_(f,c) - like Igeteof_, except EOF is an error - * cacheget_(c) - Iget_ applied to the local RILE - * cacheunget_(f,c,s) - read c backwards from cached f, executing s at BOF - * Ifileno, Ioffset_type, Irewind, Itell - analogs to stdio routines - * - * By conventions, macros whose names end in _ are statements, not expressions. - * Following such macros with `; else' results in a syntax error. - */ - -#define maps_memory (has_map_fd || has_mmap) - -#if large_memory - typedef unsigned char const *Iptr_type; - typedef struct RILE { - Iptr_type ptr, lim; - unsigned char *base; /* not Iptr_type for lint's sake */ - unsigned char *readlim; - int fd; -# if maps_memory - void (*deallocate) P((struct RILE *)); -# else - FILE *stream; -# endif - } RILE; -# if maps_memory -# define declarecache register Iptr_type ptr, lim -# define setupcache(f) (lim = (f)->lim) -# define Igeteof_(f,c,s) if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++; -# define cachegeteof_(c,s) if (ptr==lim) s else (c)= *ptr++; -# else - int Igetmore P((RILE*)); -# define declarecache register Iptr_type ptr; register RILE *rRILE -# define setupcache(f) (rRILE = (f)) -# define Igeteof_(f,c,s) if ((f)->ptr==(f)->readlim && !Igetmore(f)) s else (c)= *(f)->ptr++; -# define cachegeteof_(c,s) if (ptr==rRILE->readlim && !Igetmore(rRILE)) s else (c)= *ptr++; -# endif -# define uncache(f) ((f)->ptr = ptr) -# define cache(f) (ptr = (f)->ptr) -# define Iget_(f,c) Igeteof_(f,c,Ieof();) -# define cacheget_(c) cachegeteof_(c,Ieof();) -# define cacheunget_(f,c) (c)=(--ptr)[-1]; -# define Ioffset_type size_t -# define Itell(f) ((f)->ptr - (f)->base) -# define Irewind(f) ((f)->ptr = (f)->base) -# define cacheptr() ptr -# define Ifileno(f) ((f)->fd) -#else -# define RILE FILE -# define declarecache register FILE *ptr -# define setupcache(f) (ptr = (f)) -# define uncache(f) -# define cache(f) -# define Igeteof_(f,c,s) {if(((c)=getc(f))==EOF){testIerror(f);if(feof(f))s}} -# define cachegeteof_(c,s) Igeteof_(ptr,c,s) -# define Iget_(f,c) { if (((c)=getc(f))==EOF) testIeof(f); } -# define cacheget_(c) Iget_(ptr,c) -# define cacheunget_(f,c) if(fseek(ptr,-2L,SEEK_CUR))Ierror();else cacheget_(c) -# define Ioffset_type long -# define Itell(f) ftell(f) -# define Ifileno(f) fileno(f) -#endif - -/* Print a char, but abort on write error. */ -#define aputc_(c,o) { if (putc(c,o)==EOF) testOerror(o); } - -/* Get a character from an RCS file, perhaps copying to a new RCS file. */ -#define GETCeof_(o,c,s) { cachegeteof_(c,s) if (o) aputc_(c,o) } -#define GETC_(o,c) { cacheget_(c) if (o) aputc_(c,o) } - - -#define WORKMODE(RCSmode, writable) (((RCSmode)&(mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH)) | ((writable)?S_IWUSR:0)) -/* computes mode of working file: same as RCSmode, but write permission */ -/* determined by writable */ - - -/* character classes and token codes */ -enum tokens { -/* classes */ DELIM, DIGIT, IDCHAR, NEWLN, LETTER, Letter, - PERIOD, SBEGIN, SPACE, UNKN, -/* tokens */ COLON, ID, NUM, SEMI, STRING -}; - -#define SDELIM '@' /* the actual character is needed for string handling*/ -/* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN. - * there should be no overlap among SDELIM, KDELIM, and VDELIM - */ - -#define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than ctab[c]==DIGIT */ - - - - - -/*************************************** - * Data structures for the symbol table - ***************************************/ - -/* Buffer of arbitrary data */ -struct buf { - char *string; - size_t size; -}; -struct cbuf { - char const *string; - size_t size; -}; - -/* Hash table entry */ -struct hshentry { - char const * num; /* pointer to revision number (ASCIZ) */ - char const * date; /* pointer to date of checkin */ - char const * author; /* login of person checking in */ - char const * lockedby; /* who locks the revision */ - char const * state; /* state of revision (Exp by default) */ - char const * name; /* name (if any) by which retrieved */ - struct cbuf log; /* log message requested at checkin */ - struct branchhead * branches; /* list of first revisions on branches*/ - struct cbuf ig; /* ignored phrases in admin part */ - struct cbuf igtext; /* ignored phrases in deltatext part */ - struct hshentry * next; /* next revision on same branch */ - struct hshentry * nexthsh; /* next revision with same hash value */ - long insertlns;/* lines inserted (computed by rlog) */ - long deletelns;/* lines deleted (computed by rlog) */ - char selector; /* true if selected, false if deleted */ -}; - -/* list of hash entries */ -struct hshentries { - struct hshentries *rest; - struct hshentry *first; -}; - -/* list element for branch lists */ -struct branchhead { - struct hshentry * hsh; - struct branchhead * nextbranch; -}; - -/* accesslist element */ -struct access { - char const * login; - struct access * nextaccess; -}; - -/* list element for locks */ -struct rcslock { - char const * login; - struct hshentry * delta; - struct rcslock * nextlock; -}; - -/* list element for symbolic names */ -struct assoc { - char const * symbol; - char const * num; - struct assoc * nextassoc; -}; - - -#define mainArgs (argc,argv) int argc; char **argv; - -#if RCS_lint -# define libId(name,rcsid) -# define mainProg(name,cmd,rcsid) int name mainArgs -#else -# define libId(name,rcsid) char const name[] = rcsid; -# define mainProg(n,c,i) char const Copyright[] = "Copyright 1982,1988,1989 Walter F. Tichy, Purdue CS\nCopyright 1990,1991,1992,1993,1994,1995 Paul Eggert", baseid[] = RCSBASE, cmdid[] = c; libId(n,i) int main P((int,char**)); int main mainArgs -#endif - -/* - * Markers for keyword expansion (used in co and ident) - * Every byte must have class LETTER or Letter. - */ -#define AUTHOR "Author" -#define DATE "Date" -#define HEADER "Header" -#define IDH "Id" -#define LOCKER "Locker" -#define LOG "Log" -#define NAME "Name" -#define RCSFILE "RCSfile" -#define REVISION "Revision" -#define SOURCE "Source" -#define STATE "State" -#define CVSHEADER "CVSHeader" -#define keylength 9 /* max length of any of the above keywords */ - -enum markers { Nomatch, Author, Date, Header, Id, - Locker, Log, Name, RCSfile, Revision, Source, State, CVSHeader, - LocalId }; - /* This must be in the same order as rcskeys.c's Keyword[] array. */ - -#define DELNUMFORM "\n\n%s\n%s\n" -/* used by putdtext and scanlogtext */ - -#define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */ - -/* main program */ -extern char const cmdid[]; -void exiterr P((void)) exiting; - -/* merge */ -int merge P((int,char const*,char const*const[3],char const*const[3])); - -/* rcsedit */ -#define ciklogsize 23 /* sizeof("checked in with -k by ") */ -extern FILE *fcopy; -extern char const *resultname; -extern char const ciklog[ciklogsize]; -extern int locker_expansion; -RILE *rcswriteopen P((struct buf*,struct stat*,int)); -char const *makedirtemp P((int)); -char const *getcaller P((void)); -int addlock P((struct hshentry*,int)); -int addsymbol P((char const*,char const*,int)); -int checkaccesslist P((void)); -int chnamemod P((FILE**,char const*,char const*,int,mode_t,time_t)); -int donerewrite P((int,time_t)); -int dorewrite P((int,int)); -int expandline P((RILE*,FILE*,struct hshentry const*,int,FILE*,int)); -int findlock P((int,struct hshentry**)); -int setmtime P((char const*,time_t)); -void ORCSclose P((void)); -void ORCSerror P((void)); -void copystring P((void)); -void dirtempunlink P((void)); -void enterstring P((void)); -void finishedit P((struct hshentry const*,FILE*,int)); -void keepdirtemp P((char const*)); -void openfcopy P((FILE*)); -void snapshotedit P((FILE*)); -void xpandstring P((struct hshentry const*)); -#if has_NFS || bad_unlink - int un_link P((char const*)); -#else -# define un_link(s) unlink(s) -#endif -#if large_memory - void edit_string P((void)); -# define editstring(delta) edit_string() -#else - void editstring P((struct hshentry const*)); -#endif - -/* rcsfcmp */ -int rcsfcmp P((RILE*,struct stat const*,char const*,struct hshentry const*)); - -/* rcsfnms */ -#define bufautobegin(b) clear_buf(b) -#define clear_buf(b) (VOID ((b)->string = 0, (b)->size = 0)) -extern FILE *workstdout; -extern char *workname; -extern char const *RCSname; -extern char const *suffixes; -extern int fdlock; -extern struct stat RCSstat; -RILE *rcsreadopen P((struct buf*,struct stat*,int)); -char *bufenlarge P((struct buf*,char const**)); -char const *basefilename P((char const*)); -char const *getfullRCSname P((void)); -char const *getfullCVSname P((void)); -char const *maketemp P((int)); -char const *rcssuffix P((char const*)); -int pairnames P((int,char**,RILE*(*)P((struct buf*,struct stat*,int)),int,int)); -struct cbuf bufremember P((struct buf*,size_t)); -void bufalloc P((struct buf*,size_t)); -void bufautoend P((struct buf*)); -void bufrealloc P((struct buf*,size_t)); -void bufscat P((struct buf*,char const*)); -void bufscpy P((struct buf*,char const*)); -void tempunlink P((void)); - -/* rcsgen */ -extern int interactiveflag; -extern struct buf curlogbuf; -char const *buildrevision P((struct hshentries const*,struct hshentry*,FILE*,int)); -int getcstdin P((void)); -int putdtext P((struct hshentry const*,char const*,FILE*,int)); -int ttystdin P((void)); -int yesorno P((int,char const*,...)) printf_string(2,3); -struct cbuf cleanlogmsg P((char*,size_t)); -struct cbuf getsstdin P((char const*,char const*,char const*,struct buf*)); -void putdesc P((int,char*)); -void putdftext P((struct hshentry const*,RILE*,FILE*,int)); - -/* rcskeep */ -extern int prevkeys; -extern struct buf prevauthor, prevdate, prevname, prevrev, prevstate; -int getoldkeys P((RILE*)); - -/* rcskeys */ -extern char const *Keyword[]; -extern enum markers LocalIdMode; -enum markers trymatch P((char const*)); -void setRCSLocalId(char const *); -void setIncExc(char const *); - -/* rcslex */ -extern FILE *foutptr; -extern FILE *frewrite; -extern RILE *finptr; -extern char const *NextString; -extern enum tokens nexttok; -extern int hshenter; -extern int nerror; -extern int nextc; -extern int quietflag; -extern long rcsline; -char const *getid P((void)); -void efaterror P((char const*)) exiting; -void enfaterror P((int,char const*)) exiting; -void fatcleanup P((int)) exiting; -void faterror P((char const*,...)) printf_string_exiting(1,2); -void fatserror P((char const*,...)) printf_string_exiting(1,2); -void rcsfaterror P((char const*,...)) printf_string_exiting(1,2); -void Ieof P((void)) exiting; -void Ierror P((void)) exiting; -void Oerror P((void)) exiting; -char *checkid P((char*,int)); -char *checksym P((char*,int)); -int eoflex P((void)); -int getkeyopt P((char const*)); -int getlex P((enum tokens)); -struct cbuf getphrases P((char const*)); -struct cbuf savestring P((struct buf*)); -struct hshentry *getnum P((void)); -void Ifclose P((RILE*)); -void Izclose P((RILE**)); -void Lexinit P((void)); -void Ofclose P((FILE*)); -void Orewind P((FILE*)); -void Ozclose P((FILE**)); -void aflush P((FILE*)); -void afputc P((int,FILE*)); -void aprintf P((FILE*,char const*,...)) printf_string(2,3); -void aputs P((char const*,FILE*)); -void checksid P((char*)); -void checkssym P((char*)); -void diagnose P((char const*,...)) printf_string(1,2); -void eerror P((char const*)); -void eflush P((void)); -void enerror P((int,char const*)); -void error P((char const*,...)) printf_string(1,2); -void fvfprintf P((FILE*,char const*,va_list)); -void getkey P((char const*)); -void getkeystring P((char const*)); -void nextlex P((void)); -void oflush P((void)); -void printstring P((void)); -void readstring P((void)); -void redefined P((int)); -void rcserror P((char const*,...)) printf_string(1,2); -void rcswarn P((char const*,...)) printf_string(1,2); -void testIerror P((FILE*)); -void testOerror P((FILE*)); -void warn P((char const*,...)) printf_string(1,2); -void warnignore P((void)); -void workerror P((char const*,...)) printf_string(1,2); -void workwarn P((char const*,...)) printf_string(1,2); -#if has_madvise && has_mmap && large_memory - void advise_access P((RILE*,int)); -# define if_advise_access(p,f,advice) if (p) advise_access(f,advice) -#else -# define advise_access(f,advice) -# define if_advise_access(p,f,advice) -#endif -#if large_memory && maps_memory - RILE *I_open P((char const*,struct stat*)); -# define Iopen(f,m,s) I_open(f,s) -#else - RILE *Iopen P((char const*,char const*,struct stat*)); -#endif -#if !large_memory - void testIeof P((FILE*)); - void Irewind P((RILE*)); -#endif - -/* rcsmap */ -extern enum tokens const ctab[]; - -/* rcsrev */ -char *partialno P((struct buf*,char const*,int)); -char const *namedrev P((char const*,struct hshentry*)); -char const *tiprev P((void)); -int cmpdate P((char const*,char const*)); -int cmpnum P((char const*,char const*)); -int cmpnumfld P((char const*,char const*,int)); -int compartial P((char const*,char const*,int)); -int expandsym P((char const*,struct buf*)); -int fexpandsym P((char const*,struct buf*,RILE*)); -struct hshentry *genrevs P((char const*,char const*,char const*,char const*,struct hshentries**)); -int countnumflds P((char const*)); -void getbranchno P((char const*,struct buf*)); - -/* rcssyn */ -/* These expand modes must agree with Expand_names[] in rcssyn.c. */ -#define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */ -#define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */ -#define KEY_EXPAND 2 /* -kk `$Keyword$' */ -#define VAL_EXPAND 3 /* -kv `value' */ -#define OLD_EXPAND 4 /* -ko use old string, omitting expansion */ -#define BINARY_EXPAND 5 /* -kb like -ko, but use binary mode I/O */ -#define MIN_UNEXPAND OLD_EXPAND /* min value for no logical expansion */ -#define MIN_UNCHANGED_EXPAND (OPEN_O_BINARY ? BINARY_EXPAND : OLD_EXPAND) - /* min value guaranteed to yield an identical file */ -struct diffcmd { - long - line1, /* number of first line */ - nlines, /* number of lines affected */ - adprev, /* previous 'a' line1+1 or 'd' line1 */ - dafter; /* sum of previous 'd' line1 and previous 'd' nlines */ -}; -extern char const * Dbranch; -extern struct access * AccessList; -extern struct assoc * Symbols; -extern struct cbuf Comment; -extern struct cbuf Ignored; -extern struct rcslock *Locks; -extern struct hshentry * Head; -extern int Expand; -extern int StrictLocks; -extern int TotalDeltas; -extern char const *const expand_names[]; -extern char const - Kaccess[], Kauthor[], Kbranch[], Kcomment[], - Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[], - Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[]; -void unexpected_EOF P((void)) exiting; -int getdiffcmd P((RILE*,int,FILE*,struct diffcmd*)); -int str2expmode P((char const*)); -void getadmin P((void)); -void getdesc P((int)); -void gettree P((void)); -void ignorephrases P((char const*)); -void initdiffcmd P((struct diffcmd*)); -void putadmin P((void)); -void putstring P((FILE*,int,struct cbuf,int)); -void puttree P((struct hshentry const*,FILE*)); - -/* rcstime */ -#define zonelenmax 9 /* maxiumum length of time zone string, e.g. "+12:34:56" */ -char const *date2str P((char const[datesize],char[datesize + zonelenmax])); -time_t date2time P((char const[datesize])); -void str2date P((char const*,char[datesize])); -void time2date P((time_t,char[datesize])); -void zone_set P((char const*)); - -/* rcsutil */ -extern int RCSversion; -FILE *fopenSafer P((char const*,char const*)); -char *cgetenv P((char const*)); -char *fstr_save P((char const*)); -char *str_save P((char const*)); -char const *getusername P((int)); -int fdSafer P((int)); -int getRCSINIT P((int,char**,char***)); -int run P((int,char const*,...)); -int runv P((int,char const*,char const**)); -malloc_type fremember P((malloc_type)); -malloc_type ftestalloc P((size_t)); -malloc_type testalloc P((size_t)); -malloc_type testrealloc P((malloc_type,size_t)); -#define ftalloc(T) ftnalloc(T,1) -#define talloc(T) tnalloc(T,1) -#if RCS_lint - extern malloc_type lintalloc; -# define ftnalloc(T,n) (lintalloc = ftestalloc(sizeof(T)*(n)), (T*)0) -# define tnalloc(T,n) (lintalloc = testalloc(sizeof(T)*(n)), (T*)0) -# define trealloc(T,p,n) (lintalloc = testrealloc((malloc_type)0, sizeof(T)*(n)), p) -# define tfree(p) -#else -# define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n))) -# define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n))) -# define trealloc(T,p,n) ((T*) testrealloc((malloc_type)(p), sizeof(T)*(n))) -# define tfree(p) free((malloc_type)(p)) -#endif -time_t now P((void)); -void awrite P((char const*,size_t,FILE*)); -void fastcopy P((RILE*,FILE*)); -void ffree P((void)); -void ffree1 P((char const*)); -void setRCSversion P((char const*)); -#if has_signal - void catchints P((void)); - void ignoreints P((void)); - void restoreints P((void)); -#else -# define catchints() -# define ignoreints() -# define restoreints() -#endif -#if has_mmap && large_memory -# if has_NFS && mmap_signal - void catchmmapints P((void)); - void readAccessFilenameBuffer P((char const*,unsigned char const*)); -# else -# define catchmmapints() -# endif -#endif -#if has_getuid - uid_t ruid P((void)); -# define myself(u) ((u) == ruid()) -#else -# define myself(u) true -#endif -#if has_setuid - uid_t euid P((void)); - void nosetid P((void)); - void seteid P((void)); - void setrid P((void)); -#else -# define nosetid() -# define seteid() -# define setrid() -#endif - -/* version */ -extern char const RCS_version_string[]; diff --git a/gnu/usr.bin/rcs/lib/rcsedit.c b/gnu/usr.bin/rcs/lib/rcsedit.c deleted file mode 100644 index dc9dd30..0000000 --- a/gnu/usr.bin/rcs/lib/rcsedit.c +++ /dev/null @@ -1,1958 +0,0 @@ -/* RCS stream editor */ - -/****************************************************************************** - * edits the input file according to a - * script from stdin, generated by diff -n - * performs keyword expansion - ****************************************************************************** - */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.19 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.18 1995/06/01 16:23:43 eggert - * (dirtpname): No longer external. - * (do_link): Simplify logic. - * (finisheditline, finishedit): Replace Iseek/Itell with what they stand for. - * (fopen_update_truncate): Replace `#if' with `if'. - * (keyreplace, makedirtemp): dirlen(x) -> basefilename(x)-x. - * - * (edit_string): Fix bug: if !large_memory, a bogus trailing `@' was output - * at the end of incomplete lines. - * - * (keyreplace): Do not assume that seeking backwards - * at the start of a file will fail; on some systems it succeeds. - * Convert C- and Pascal-style comment starts to ` *' in comment leader. - * - * (rcswriteopen): Use fdSafer to get safer file descriptor. - * Open RCS file with FOPEN_RB. - * - * (chnamemod): Work around bad_NFS_rename bug; don't ignore un_link result. - * Fall back on chmod if fchmod fails, since it might be ENOSYS. - * - * (aflush): Move to rcslex.c. - * - * Revision 5.17 1994/03/20 04:52:58 eggert - * Normally calculate the $Log prefix from context, not from RCS file. - * Move setmtime here from rcsutil.c. Add ORCSerror. Remove lint. - * - * Revision 5.16 1993/11/03 17:42:27 eggert - * Add -z. Add Name keyword. If bad_unlink, ignore errno when unlink fails. - * Escape white space, $, and \ in keyword string file names. - * Don't output 2 spaces between date and time after Log. - * - * Revision 5.15 1992/07/28 16:12:44 eggert - * Some hosts have readlink but not ELOOP. Avoid `unsigned'. - * Preserve dates more systematically. Statement macro names now end in _. - * - * Revision 5.14 1992/02/17 23:02:24 eggert - * Add -T support. - * - * Revision 5.13 1992/01/24 18:44:19 eggert - * Add support for bad_chmod_close, bad_creat0. - * - * Revision 5.12 1992/01/06 02:42:34 eggert - * Add setmode parameter to chnamemod. addsymbol now reports changes. - * while (E) ; -> while (E) continue; - * - * Revision 5.11 1991/11/03 01:11:44 eggert - * Move the warning about link breaking to where they're actually being broken. - * - * Revision 5.10 1991/10/07 17:32:46 eggert - * Support piece tables even if !has_mmap. Fix rare NFS bugs. - * - * Revision 5.9 1991/09/17 19:07:40 eggert - * SGI readlink() yields ENXIO, not EINVAL, for nonlinks. - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Add piece tables, NFS bug workarounds. Catch odd filenames. Tune. - * - * Revision 5.7 1991/04/21 11:58:21 eggert - * Fix errno bugs. Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.6 1991/02/25 07:12:40 eggert - * Fix setuid bug. Support new link behavior. Work around broken "w+" fopen. - * - * Revision 5.5 1990/12/30 05:07:35 eggert - * Fix report of busy RCS files when !defined(O_CREAT) | !defined(O_EXCL). - * - * Revision 5.4 1990/11/01 05:03:40 eggert - * Permit arbitrary data in comment leaders. - * - * Revision 5.3 1990/09/11 02:41:13 eggert - * Tune expandline(). - * - * Revision 5.2 1990/09/04 08:02:21 eggert - * Count RCS lines better. Improve incomplete line handling. - * - * Revision 5.1 1990/08/29 07:13:56 eggert - * Add -kkvl. - * Fix bug when getting revisions to files ending in incomplete lines. - * Fix bug in comment leader expansion. - * - * Revision 5.0 1990/08/22 08:12:47 eggert - * Don't require final newline. - * Don't append "checked in with -k by " to logs, - * so that checking in a program with -k doesn't change it. - * Don't generate trailing white space for empty comment leader. - * Remove compile-time limits; use malloc instead. Add -k, -V. - * Permit dates past 1999/12/31. Make lock and temp files faster and safer. - * Ansify and Posixate. Check diff's output. - * - * Revision 4.8 89/05/01 15:12:35 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.7 88/11/08 13:54:14 narten - * misplaced semicolon caused infinite loop - * - * Revision 4.6 88/08/09 19:12:45 eggert - * Shrink stdio code size; allow cc -R. - * - * Revision 4.5 87/12/18 11:38:46 narten - * Changes from the 43. version. Don't know the significance of the - * first change involving "rewind". Also, additional "lint" cleanup. - * (Guy Harris) - * - * Revision 4.4 87/10/18 10:32:21 narten - * Updating version numbers. Changes relative to version 1.1 actually - * relative to 4.1 - * - * Revision 1.4 87/09/24 13:59:29 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.3 87/09/15 16:39:39 shepler - * added an initializatin of the variables editline and linecorr - * this will be done each time a file is processed. - * (there was an obscure bug where if co was used to retrieve multiple files - * it would dump) - * fix attributed to Roy Morris @FileNet Corp ...!felix!roy - * - * Revision 1.2 87/03/27 14:22:17 jenkins - * Port to suns - * - * Revision 4.1 83/05/12 13:10:30 wft - * Added new markers Id and RCSfile; added locker to Header and Id. - * Overhauled expandline completely() (problem with $01234567890123456789@). - * Moved trymatch() and marker table to rcskeys.c. - * - * Revision 3.7 83/05/12 13:04:39 wft - * Added retry to expandline to resume after failed match which ended in $. - * Fixed truncation problem for $19chars followed by@@. - * Log no longer expands full path of RCS file. - * - * Revision 3.6 83/05/11 16:06:30 wft - * added retry to expandline to resume after failed match which ended in $. - * Fixed truncation problem for $19chars followed by@@. - * - * Revision 3.5 82/12/04 13:20:56 wft - * Added expansion of keyword Locker. - * - * Revision 3.4 82/12/03 12:26:54 wft - * Added line number correction in case editing does not start at the - * beginning of the file. - * Changed keyword expansion to always print a space before closing KDELIM; - * Expansion for Header shortened. - * - * Revision 3.3 82/11/14 14:49:30 wft - * removed Suffix from keyword expansion. Replaced fclose with ffclose. - * keyreplace() gets log message from delta, not from curlogmsg. - * fixed expression overflow in while(c=putc(GETC.... - * checked nil printing. - * - * Revision 3.2 82/10/18 21:13:39 wft - * I added checks for write errors during the co process, and renamed - * expandstring() to xpandstring(). - * - * Revision 3.1 82/10/13 15:52:55 wft - * changed type of result of getc() from char to int. - * made keyword expansion loop in expandline() portable to machines - * without sign-extension. - */ - - -#include "rcsbase.h" - -libId(editId, "$FreeBSD$") - -static void editEndsPrematurely P((void)) exiting; -static void editLineNumberOverflow P((void)) exiting; -static void escape_string P((FILE*,char const*)); -static void keyreplace P((enum markers,struct hshentry const*,int,RILE*,FILE*,int)); - -FILE *fcopy; /* result file descriptor */ -char const *resultname; /* result pathname */ -int locker_expansion; /* should the locker name be appended to Id val? */ -#if !large_memory - static RILE *fedit; /* edit file descriptor */ - static char const *editname; /* edit pathname */ -#endif -static long editline; /* edit line counter; #lines before cursor */ -static long linecorr; /* #adds - #deletes in each edit run. */ - /*used to correct editline in case file is not rewound after */ - /* applying one delta */ - -/* indexes into dirtpname */ -#define lockdirtp_index 0 -#define newRCSdirtp_index bad_creat0 -#define newworkdirtp_index (newRCSdirtp_index+1) -#define DIRTEMPNAMES (newworkdirtp_index + 1) - -enum maker {notmade, real, effective}; -static struct buf dirtpname[DIRTEMPNAMES]; /* unlink these when done */ -static enum maker volatile dirtpmaker[DIRTEMPNAMES]; /* if these are set */ -#define lockname (dirtpname[lockdirtp_index].string) -#define newRCSname (dirtpname[newRCSdirtp_index].string) - - -#if has_NFS || bad_unlink - int -un_link(s) - char const *s; -/* - * Remove S, even if it is unwritable. - * Ignore unlink() ENOENT failures; NFS generates bogus ones. - */ -{ -# if bad_unlink - if (unlink(s) == 0) - return 0; - else { - int e = errno; - /* - * Forge ahead even if errno == ENOENT; some completely - * brain-damaged hosts (e.g. PCTCP 2.2) yield ENOENT - * even for existing unwritable files. - */ - if (chmod(s, S_IWUSR) != 0) { - errno = e; - return -1; - } - } -# endif -# if has_NFS - return unlink(s)==0 || errno==ENOENT ? 0 : -1; -# else - return unlink(s); -# endif -} -#endif - -#if !has_rename -# if !has_NFS -# define do_link(s,t) link(s,t) -# else - static int do_link P((char const*,char const*)); - static int -do_link(s, t) - char const *s, *t; -/* Link S to T, ignoring bogus EEXIST problems due to NFS failures. */ -{ - int r = link(s, t); - - if (r != 0 && errno == EEXIST) { - struct stat sb, tb; - if ( - stat(s, &sb) == 0 && - stat(t, &tb) == 0 && - same_file(sb, tb, 0) - ) - r = 0; - errno = EEXIST; - } - return r; -} -# endif -#endif - - - static void -editEndsPrematurely() -{ - fatserror("edit script ends prematurely"); -} - - static void -editLineNumberOverflow() -{ - fatserror("edit script refers to line past end of file"); -} - - -#if large_memory - -#if has_memmove -# define movelines(s1, s2, n) VOID memmove(s1, s2, (n)*sizeof(Iptr_type)) -#else - static void movelines P((Iptr_type*,Iptr_type const*,long)); - static void -movelines(s1, s2, n) - register Iptr_type *s1; - register Iptr_type const *s2; - register long n; -{ - if (s1 < s2) - do { - *s1++ = *s2++; - } while (--n); - else { - s1 += n; - s2 += n; - do { - *--s1 = *--s2; - } while (--n); - } -} -#endif - -static void deletelines P((long,long)); -static void finisheditline P((RILE*,FILE*,Iptr_type,struct hshentry const*)); -static void insertline P((long,Iptr_type)); -static void snapshotline P((FILE*,Iptr_type)); - -/* - * `line' contains pointers to the lines in the currently `edited' file. - * It is a 0-origin array that represents linelim-gapsize lines. - * line[0 .. gap-1] and line[gap+gapsize .. linelim-1] hold pointers to lines. - * line[gap .. gap+gapsize-1] contains garbage. - * - * Any @s in lines are duplicated. - * Lines are terminated by \n, or (for a last partial line only) by single @. - */ -static Iptr_type *line; -static size_t gap, gapsize, linelim; - - static void -insertline(n, l) - long n; - Iptr_type l; -/* Before line N, insert line L. N is 0-origin. */ -{ - if (linelim-gapsize < n) - editLineNumberOverflow(); - if (!gapsize) - line = - !linelim ? - tnalloc(Iptr_type, linelim = gapsize = 1024) - : ( - gap = gapsize = linelim, - trealloc(Iptr_type, line, linelim <<= 1) - ); - if (n < gap) - movelines(line+n+gapsize, line+n, gap-n); - else if (gap < n) - movelines(line+gap, line+gap+gapsize, n-gap); - - line[n] = l; - gap = n + 1; - gapsize--; -} - - static void -deletelines(n, nlines) - long n, nlines; -/* Delete lines N through N+NLINES-1. N is 0-origin. */ -{ - long l = n + nlines; - if (linelim-gapsize < l || l < n) - editLineNumberOverflow(); - if (l < gap) - movelines(line+l+gapsize, line+l, gap-l); - else if (gap < n) - movelines(line+gap, line+gap+gapsize, n-gap); - - gap = n; - gapsize += nlines; -} - - static void -snapshotline(f, l) - register FILE *f; - register Iptr_type l; -{ - register int c; - do { - if ((c = *l++) == SDELIM && *l++ != SDELIM) - return; - aputc_(c, f) - } while (c != '\n'); -} - - void -snapshotedit(f) - FILE *f; -/* Copy the current state of the edits to F. */ -{ - register Iptr_type *p, *lim, *l=line; - for (p=l, lim=l+gap; p<lim; ) - snapshotline(f, *p++); - for (p+=gapsize, lim=l+linelim; p<lim; ) - snapshotline(f, *p++); -} - - static void -finisheditline(fin, fout, l, delta) - RILE *fin; - FILE *fout; - Iptr_type l; - struct hshentry const *delta; -{ - fin->ptr = l; - if (expandline(fin, fout, delta, true, (FILE*)0, true) < 0) - faterror("finisheditline internal error"); -} - - void -finishedit(delta, outfile, done) - struct hshentry const *delta; - FILE *outfile; - int done; -/* - * Doing expansion if DELTA is set, output the state of the edits to OUTFILE. - * But do nothing unless DONE is set (which means we are on the last pass). - */ -{ - if (done) { - openfcopy(outfile); - outfile = fcopy; - if (!delta) - snapshotedit(outfile); - else { - register Iptr_type *p, *lim, *l = line; - register RILE *fin = finptr; - Iptr_type here = fin->ptr; - for (p=l, lim=l+gap; p<lim; ) - finisheditline(fin, outfile, *p++, delta); - for (p+=gapsize, lim=l+linelim; p<lim; ) - finisheditline(fin, outfile, *p++, delta); - fin->ptr = here; - } - } -} - -/* Open a temporary NAME for output, truncating any previous contents. */ -# define fopen_update_truncate(name) fopenSafer(name, FOPEN_W_WORK) -#else /* !large_memory */ - static FILE * fopen_update_truncate P((char const*)); - static FILE * -fopen_update_truncate(name) - char const *name; -{ - if (bad_fopen_wplus && un_link(name) != 0) - efaterror(name); - return fopenSafer(name, FOPEN_WPLUS_WORK); -} -#endif - - - void -openfcopy(f) - FILE *f; -{ - if (!(fcopy = f)) { - if (!resultname) - resultname = maketemp(2); - if (!(fcopy = fopen_update_truncate(resultname))) - efaterror(resultname); - } -} - - -#if !large_memory - - static void swapeditfiles P((FILE*)); - static void -swapeditfiles(outfile) - FILE *outfile; -/* Function: swaps resultname and editname, assigns fedit=fcopy, - * and rewinds fedit for reading. Set fcopy to outfile if nonnull; - * otherwise, set fcopy to be resultname opened for reading and writing. - */ -{ - char const *tmpptr; - - editline = 0; linecorr = 0; - Orewind(fcopy); - fedit = fcopy; - tmpptr=editname; editname=resultname; resultname=tmpptr; - openfcopy(outfile); -} - - void -snapshotedit(f) - FILE *f; -/* Copy the current state of the edits to F. */ -{ - finishedit((struct hshentry *)0, (FILE*)0, false); - fastcopy(fedit, f); - Irewind(fedit); -} - - void -finishedit(delta, outfile, done) - struct hshentry const *delta; - FILE *outfile; - int done; -/* copy the rest of the edit file and close it (if it exists). - * if delta, perform keyword substitution at the same time. - * If DONE is set, we are finishing the last pass. - */ -{ - register RILE *fe; - register FILE *fc; - - fe = fedit; - if (fe) { - fc = fcopy; - if (delta) { - while (1 < expandline(fe,fc,delta,false,(FILE*)0,true)) - ; - } else { - fastcopy(fe,fc); - } - Ifclose(fe); - } - if (!done) - swapeditfiles(outfile); -} -#endif - - - -#if large_memory -# define copylines(upto,delta) (editline = (upto)) -#else - static void copylines P((long,struct hshentry const*)); - static void -copylines(upto, delta) - register long upto; - struct hshentry const *delta; -/* - * Copy input lines editline+1..upto from fedit to fcopy. - * If delta, keyword expansion is done simultaneously. - * editline is updated. Rewinds a file only if necessary. - */ -{ - register int c; - declarecache; - register FILE *fc; - register RILE *fe; - - if (upto < editline) { - /* swap files */ - finishedit((struct hshentry *)0, (FILE*)0, false); - /* assumes edit only during last pass, from the beginning*/ - } - fe = fedit; - fc = fcopy; - if (editline < upto) - if (delta) - do { - if (expandline(fe,fc,delta,false,(FILE*)0,true) <= 1) - editLineNumberOverflow(); - } while (++editline < upto); - else { - setupcache(fe); cache(fe); - do { - do { - cachegeteof_(c, editLineNumberOverflow();) - aputc_(c, fc) - } while (c != '\n'); - } while (++editline < upto); - uncache(fe); - } -} -#endif - - - - void -xpandstring(delta) - struct hshentry const *delta; -/* Function: Reads a string terminated by SDELIM from finptr and writes it - * to fcopy. Double SDELIM is replaced with single SDELIM. - * Keyword expansion is performed with data from delta. - * If foutptr is nonnull, the string is also copied unchanged to foutptr. - */ -{ - while (1 < expandline(finptr,fcopy,delta,true,foutptr,true)) - continue; -} - - - void -copystring() -/* Function: copies a string terminated with a single SDELIM from finptr to - * fcopy, replacing all double SDELIM with a single SDELIM. - * If foutptr is nonnull, the string also copied unchanged to foutptr. - * editline is incremented by the number of lines copied. - * Assumption: next character read is first string character. - */ -{ register c; - declarecache; - register FILE *frew, *fcop; - register int amidline; - register RILE *fin; - - fin = finptr; - setupcache(fin); cache(fin); - frew = foutptr; - fcop = fcopy; - amidline = false; - for (;;) { - GETC_(frew,c) - switch (c) { - case '\n': - ++editline; - ++rcsline; - amidline = false; - break; - case SDELIM: - GETC_(frew,c) - if (c != SDELIM) { - /* end of string */ - nextc = c; - editline += amidline; - uncache(fin); - return; - } - /* fall into */ - default: - amidline = true; - break; - } - aputc_(c,fcop) - } -} - - - void -enterstring() -/* Like copystring, except the string is put into the edit data structure. */ -{ -#if !large_memory - editname = 0; - fedit = 0; - editline = linecorr = 0; - resultname = maketemp(1); - if (!(fcopy = fopen_update_truncate(resultname))) - efaterror(resultname); - copystring(); -#else - register int c; - declarecache; - register FILE *frew; - register long e, oe; - register int amidline, oamidline; - register Iptr_type optr; - register RILE *fin; - - e = 0; - gap = 0; - gapsize = linelim; - fin = finptr; - setupcache(fin); cache(fin); - advise_access(fin, MADV_NORMAL); - frew = foutptr; - amidline = false; - for (;;) { - optr = cacheptr(); - GETC_(frew,c) - oamidline = amidline; - oe = e; - switch (c) { - case '\n': - ++e; - ++rcsline; - amidline = false; - break; - case SDELIM: - GETC_(frew,c) - if (c != SDELIM) { - /* end of string */ - nextc = c; - editline = e + amidline; - linecorr = 0; - uncache(fin); - return; - } - /* fall into */ - default: - amidline = true; - break; - } - if (!oamidline) - insertline(oe, optr); - } -#endif -} - - - - - void -#if large_memory -edit_string() -#else - editstring(delta) - struct hshentry const *delta; -#endif -/* - * Read an edit script from finptr and applies it to the edit file. -#if !large_memory - * The result is written to fcopy. - * If delta, keyword expansion is performed simultaneously. - * If running out of lines in fedit, fedit and fcopy are swapped. - * editname is the name of the file that goes with fedit. -#endif - * If foutptr is set, the edit script is also copied verbatim to foutptr. - * Assumes that all these files are open. - * resultname is the name of the file that goes with fcopy. - * Assumes the next input character from finptr is the first character of - * the edit script. Resets nextc on exit. - */ -{ - int ed; /* editor command */ - register int c; - declarecache; - register FILE *frew; -# if !large_memory - register FILE *f; - long line_lim = LONG_MAX; - register RILE *fe; -# endif - register long i; - register RILE *fin; -# if large_memory - register long j; -# endif - struct diffcmd dc; - - editline += linecorr; linecorr=0; /*correct line number*/ - frew = foutptr; - fin = finptr; - setupcache(fin); - initdiffcmd(&dc); - while (0 <= (ed = getdiffcmd(fin,true,frew,&dc))) -#if !large_memory - if (line_lim <= dc.line1) - editLineNumberOverflow(); - else -#endif - if (!ed) { - copylines(dc.line1-1, delta); - /* skip over unwanted lines */ - i = dc.nlines; - linecorr -= i; - editline += i; -# if large_memory - deletelines(editline+linecorr, i); -# else - fe = fedit; - do { - /*skip next line*/ - do { - Igeteof_(fe, c, { if (i!=1) editLineNumberOverflow(); line_lim = dc.dafter; break; } ) - } while (c != '\n'); - } while (--i); -# endif - } else { - /* Copy lines without deleting any. */ - copylines(dc.line1, delta); - i = dc.nlines; -# if large_memory - j = editline+linecorr; -# endif - linecorr += i; -#if !large_memory - f = fcopy; - if (delta) - do { - switch (expandline(fin,f,delta,true,frew,true)){ - case 0: case 1: - if (i==1) - return; - /* fall into */ - case -1: - editEndsPrematurely(); - } - } while (--i); - else -#endif - { - cache(fin); - do { -# if large_memory - insertline(j++, cacheptr()); -# endif - for (;;) { - GETC_(frew, c) - if (c==SDELIM) { - GETC_(frew, c) - if (c!=SDELIM) { - if (--i) - editEndsPrematurely(); - nextc = c; - uncache(fin); - return; - } - } -# if !large_memory - aputc_(c, f) -# endif - if (c == '\n') - break; - } - ++rcsline; - } while (--i); - uncache(fin); - } - } -} - - - -/* The rest is for keyword expansion */ - - - - int -expandline(infile, outfile, delta, delimstuffed, frewfile, dolog) - RILE *infile; - FILE *outfile, *frewfile; - struct hshentry const *delta; - int delimstuffed, dolog; -/* - * Read a line from INFILE and write it to OUTFILE. - * Do keyword expansion with data from DELTA. - * If DELIMSTUFFED is true, double SDELIM is replaced with single SDELIM. - * If FREWFILE is set, copy the line unchanged to FREWFILE. - * DELIMSTUFFED must be true if FREWFILE is set. - * Append revision history to log only if DOLOG is set. - * Yields -1 if no data is copied, 0 if an incomplete line is copied, - * 2 if a complete line is copied; adds 1 to yield if expansion occurred. - */ -{ - register c; - declarecache; - register FILE *out, *frew; - register char * tp; - register int e, ds, r; - char const *tlim; - static struct buf keyval; - enum markers matchresult; - - setupcache(infile); cache(infile); - out = outfile; - frew = frewfile; - ds = delimstuffed; - bufalloc(&keyval, keylength+3); - e = 0; - r = -1; - - for (;;) { - if (ds) - GETC_(frew, c) - else - cachegeteof_(c, goto uncache_exit;) - for (;;) { - switch (c) { - case SDELIM: - if (ds) { - GETC_(frew, c) - if (c != SDELIM) { - /* end of string */ - nextc=c; - goto uncache_exit; - } - } - /* fall into */ - default: - aputc_(c,out) - r = 0; - break; - - case '\n': - rcsline += ds; - aputc_(c,out) - r = 2; - goto uncache_exit; - - case KDELIM: - r = 0; - /* check for keyword */ - /* first, copy a long enough string into keystring */ - tp = keyval.string; - *tp++ = KDELIM; - for (;;) { - if (ds) - GETC_(frew, c) - else - cachegeteof_(c, goto keystring_eof;) - if (tp <= &keyval.string[keylength]) - switch (ctab[c]) { - case LETTER: case Letter: - *tp++ = c; - continue; - default: - break; - } - break; - } - *tp++ = c; *tp = '\0'; - matchresult = trymatch(keyval.string+1); - if (matchresult==Nomatch) { - tp[-1] = 0; - aputs(keyval.string, out); - continue; /* last c handled properly */ - } - - /* Now we have a keyword terminated with a K/VDELIM */ - if (c==VDELIM) { - /* try to find closing KDELIM, and replace value */ - tlim = keyval.string + keyval.size; - for (;;) { - if (ds) - GETC_(frew, c) - else - cachegeteof_(c, goto keystring_eof;) - if (c=='\n' || c==KDELIM) - break; - *tp++ =c; - if (tlim <= tp) - tp = bufenlarge(&keyval, &tlim); - if (c==SDELIM && ds) { /*skip next SDELIM */ - GETC_(frew, c) - if (c != SDELIM) { - /* end of string before closing KDELIM or newline */ - nextc = c; - goto keystring_eof; - } - } - } - if (c!=KDELIM) { - /* couldn't find closing KDELIM -- give up */ - *tp = 0; - aputs(keyval.string, out); - continue; /* last c handled properly */ - } - } - /* now put out the new keyword value */ - uncache(infile); - keyreplace(matchresult, delta, ds, infile, out, dolog); - cache(infile); - e = 1; - break; - } - break; - } - } - - keystring_eof: - *tp = 0; - aputs(keyval.string, out); - uncache_exit: - uncache(infile); - return r + e; -} - - - static void -escape_string(out, s) - register FILE *out; - register char const *s; -/* Output to OUT the string S, escaping chars that would break `ci -k'. */ -{ - register char c; - for (;;) - switch ((c = *s++)) { - case 0: return; - case '\t': aputs("\\t", out); break; - case '\n': aputs("\\n", out); break; - case ' ': aputs("\\040", out); break; - case KDELIM: aputs("\\044", out); break; - case '\\': if (VERSION(5)<=RCSversion) {aputs("\\\\", out); break;} - /* fall into */ - default: aputc_(c, out) break; - } -} - -char const ciklog[ciklogsize] = "checked in with -k by "; - - static void -keyreplace(marker, delta, delimstuffed, infile, out, dolog) - enum markers marker; - register struct hshentry const *delta; - int delimstuffed; - RILE *infile; - register FILE *out; - int dolog; -/* function: outputs the keyword value(s) corresponding to marker. - * Attributes are derived from delta. - */ -{ - register char const *sp, *cp, *date; - register int c; - register size_t cs, cw, ls; - char const *sp1; - char datebuf[datesize + zonelenmax]; - int RCSv; - int exp; - - sp = Keyword[(int)marker]; - exp = Expand; - date = delta->date; - RCSv = RCSversion; - - if (exp != VAL_EXPAND) - aprintf(out, "%c%s", KDELIM, sp); - if (exp != KEY_EXPAND) { - - if (exp != VAL_EXPAND) - aprintf(out, "%c%c", VDELIM, - marker==Log && RCSv<VERSION(5) ? '\t' : ' ' - ); - - switch (marker) { - case Author: - aputs(delta->author, out); - break; - case Date: - aputs(date2str(date,datebuf), out); - break; - case Id: - case LocalId: - case Header: - case CVSHeader: - if (marker == Id || RCSv < VERSION(4) || - (marker == LocalId && LocalIdMode == Id)) - escape_string(out, basefilename(RCSname)); - else if (marker == CVSHeader || - (marker == LocalId && LocalIdMode == CVSHeader)) - escape_string(out, getfullCVSname()); - else - escape_string(out, getfullRCSname()); - aprintf(out, " %s %s %s %s", - delta->num, - date2str(date, datebuf), - delta->author, - RCSv==VERSION(3) && delta->lockedby ? "Locked" - : delta->state - ); - if (delta->lockedby) - if (VERSION(5) <= RCSv) { - if (locker_expansion || exp==KEYVALLOCK_EXPAND) - aprintf(out, " %s", delta->lockedby); - } else if (RCSv == VERSION(4)) - aprintf(out, " Locker: %s", delta->lockedby); - break; - case Locker: - if (delta->lockedby) - if ( - locker_expansion - || exp == KEYVALLOCK_EXPAND - || RCSv <= VERSION(4) - ) - aputs(delta->lockedby, out); - break; - case Log: - case RCSfile: - escape_string(out, basefilename(RCSname)); - break; - case Name: - if (delta->name) - aputs(delta->name, out); - break; - case Revision: - aputs(delta->num, out); - break; - case Source: - escape_string(out, getfullRCSname()); - break; - case State: - aputs(delta->state, out); - break; - default: - break; - } - if (exp != VAL_EXPAND) - afputc(' ', out); - } - if (exp != VAL_EXPAND) - afputc(KDELIM, out); - - if (marker == Log && dolog) { - struct buf leader; - - sp = delta->log.string; - ls = delta->log.size; - if (sizeof(ciklog)-1<=ls && !memcmp(sp,ciklog,sizeof(ciklog)-1)) - return; - bufautobegin(&leader); - if (RCSversion < VERSION(5)) { - cp = Comment.string; - cs = Comment.size; - } else { - int kdelim_found = 0; - Ioffset_type chars_read = Itell(infile); - declarecache; - setupcache(infile); cache(infile); - - c = 0; /* Pacify `gcc -Wall'. */ - - /* - * Back up to the start of the current input line, - * setting CS to the number of characters before `$Log'. - */ - cs = 0; - for (;;) { - if (!--chars_read) - goto done_backing_up; - cacheunget_(infile, c) - if (c == '\n') - break; - if (c == SDELIM && delimstuffed) { - if (!--chars_read) - break; - cacheunget_(infile, c) - if (c != SDELIM) { - cacheget_(c) - break; - } - } - cs += kdelim_found; - kdelim_found |= c==KDELIM; - } - cacheget_(c) - done_backing_up:; - - /* Copy characters before `$Log' into LEADER. */ - bufalloc(&leader, cs); - cp = leader.string; - for (cw = 0; cw < cs; cw++) { - leader.string[cw] = c; - if (c == SDELIM && delimstuffed) - cacheget_(c) - cacheget_(c) - } - - /* Convert traditional C or Pascal leader to ` *'. */ - for (cw = 0; cw < cs; cw++) - if (ctab[(unsigned char) cp[cw]] != SPACE) - break; - if ( - cw+1 < cs - && cp[cw+1] == '*' - && (cp[cw] == '/' || cp[cw] == '(') - ) { - size_t i = cw+1; - for (;;) - if (++i == cs) { - warn( - "`%c* $Log' is obsolescent; use ` * $Log'.", - cp[cw] - ); - leader.string[cw] = ' '; - break; - } else if (ctab[(unsigned char) cp[i]] != SPACE) - break; - } - - /* Skip `$Log ... $' string. */ - do { - cacheget_(c) - } while (c != KDELIM); - uncache(infile); - } - afputc('\n', out); - awrite(cp, cs, out); - sp1 = date2str(date, datebuf); - if (VERSION(5) <= RCSv) { - aprintf(out, "Revision %s %s %s", - delta->num, sp1, delta->author - ); - } else { - /* oddity: 2 spaces between date and time, not 1 as usual */ - sp1 = strchr(sp1, ' '); - aprintf(out, "Revision %s %.*s %s %s", - delta->num, (int)(sp1-datebuf), datebuf, sp1, - delta->author - ); - } - /* Do not include state: it may change and is not updated. */ - cw = cs; - if (VERSION(5) <= RCSv) - for (; cw && (cp[cw-1]==' ' || cp[cw-1]=='\t'); --cw) - continue; - for (;;) { - afputc('\n', out); - awrite(cp, cw, out); - if (!ls) - break; - --ls; - c = *sp++; - if (c != '\n') { - awrite(cp+cw, cs-cw, out); - do { - afputc(c,out); - if (!ls) - break; - --ls; - c = *sp++; - } while (c != '\n'); - } - } - bufautoend(&leader); - } -} - -#if has_readlink - static int resolve_symlink P((struct buf*)); - static int -resolve_symlink(L) - struct buf *L; -/* - * If L is a symbolic link, resolve it to the name that it points to. - * If unsuccessful, set errno and yield -1. - * If it points to an existing file, yield 1. - * Otherwise, set errno=ENOENT and yield 0. - */ -{ - char *b, a[SIZEABLE_PATH]; - int e; - size_t s; - ssize_t r; - struct buf bigbuf; - int linkcount = MAXSYMLINKS; - - b = a; - s = sizeof(a); - bufautobegin(&bigbuf); - while ((r = readlink(L->string,b,s)) != -1) - if (r == s) { - bufalloc(&bigbuf, s<<1); - b = bigbuf.string; - s = bigbuf.size; - } else if (!linkcount--) { -# ifndef ELOOP - /* - * Some pedantic Posix 1003.1-1990 hosts have readlink - * but not ELOOP. Approximate ELOOP with EMLINK. - */ -# define ELOOP EMLINK -# endif - errno = ELOOP; - return -1; - } else { - /* Splice symbolic link into L. */ - b[r] = '\0'; - L->string[ - ROOTPATH(b) ? 0 : basefilename(L->string) - L->string - ] = '\0'; - bufscat(L, b); - } - e = errno; - bufautoend(&bigbuf); - errno = e; - switch (e) { - case readlink_isreg_errno: return 1; - case ENOENT: return 0; - default: return -1; - } -} -#endif - - RILE * -rcswriteopen(RCSbuf, status, mustread) - struct buf *RCSbuf; - struct stat *status; - int mustread; -/* - * Create the lock file corresponding to RCSBUF. - * Then try to open RCSBUF for reading and yield its RILE* descriptor. - * Put its status into *STATUS too. - * MUSTREAD is true if the file must already exist, too. - * If all goes well, discard any previously acquired locks, - * and set fdlock to the file descriptor of the RCS lockfile. - */ -{ - register char *tp; - register char const *sp, *RCSpath, *x; - RILE *f; - size_t l; - int e, exists, fdesc, fdescSafer, r, waslocked; - struct buf *dirt; - struct stat statbuf; - - waslocked = 0 <= fdlock; - exists = -# if has_readlink - resolve_symlink(RCSbuf); -# else - stat(RCSbuf->string, &statbuf) == 0 ? 1 - : errno==ENOENT ? 0 : -1; -# endif - if (exists < (mustread|waslocked)) - /* - * There's an unusual problem with the RCS file; - * or the RCS file doesn't exist, - * and we must read or we already have a lock elsewhere. - */ - return 0; - - RCSpath = RCSbuf->string; - sp = basefilename(RCSpath); - l = sp - RCSpath; - dirt = &dirtpname[waslocked]; - bufscpy(dirt, RCSpath); - tp = dirt->string + l; - x = rcssuffix(RCSpath); -# if has_readlink - if (!x) { - error("symbolic link to non RCS file `%s'", RCSpath); - errno = EINVAL; - return 0; - } -# endif - if (*sp == *x) { - error("RCS pathname `%s' incompatible with suffix `%s'", sp, x); - errno = EINVAL; - return 0; - } - /* Create a lock filename that is a function of the RCS filename. */ - if (*x) { - /* - * The suffix is nonempty. - * The lock filename is the first char of of the suffix, - * followed by the RCS filename with last char removed. E.g.: - * foo,v RCS filename with suffix ,v - * ,foo, lock filename - */ - *tp++ = *x; - while (*sp) - *tp++ = *sp++; - *--tp = 0; - } else { - /* - * The suffix is empty. - * The lock filename is the RCS filename - * with last char replaced by '_'. - */ - while ((*tp++ = *sp++)) - continue; - tp -= 2; - if (*tp == '_') { - error("RCS pathname `%s' ends with `%c'", RCSpath, *tp); - errno = EINVAL; - return 0; - } - *tp = '_'; - } - - sp = dirt->string; - - f = 0; - - /* - * good news: - * open(f, O_CREAT|O_EXCL|O_TRUNC|..., OPEN_CREAT_READONLY) - * is atomic according to Posix 1003.1-1990. - * bad news: - * NFS ignores O_EXCL and doesn't comply with Posix 1003.1-1990. - * good news: - * (O_TRUNC,OPEN_CREAT_READONLY) normally guarantees atomicity - * even with NFS. - * bad news: - * If you're root, (O_TRUNC,OPEN_CREAT_READONLY) doesn't - * guarantee atomicity. - * good news: - * Root-over-the-wire NFS access is rare for security reasons. - * This bug has never been reported in practice with RCS. - * So we don't worry about this bug. - * - * An even rarer NFS bug can occur when clients retry requests. - * This can happen in the usual case of NFS over UDP. - * Suppose client A releases a lock by renaming ",f," to "f,v" at - * about the same time that client B obtains a lock by creating ",f,", - * and suppose A's first rename request is delayed, so A reissues it. - * The sequence of events might be: - * A sends rename(",f,", "f,v") - * B sends create(",f,") - * A sends retry of rename(",f,", "f,v") - * server receives, does, and acknowledges A's first rename() - * A receives acknowledgment, and its RCS program exits - * server receives, does, and acknowledges B's create() - * server receives, does, and acknowledges A's retry of rename() - * This not only wrongly deletes B's lock, it removes the RCS file! - * Most NFS implementations have idempotency caches that usually prevent - * this scenario, but such caches are finite and can be overrun. - * This problem afflicts not only RCS, which uses open() and rename() - * to get and release locks; it also afflicts the traditional - * Unix method of using link() and unlink() to get and release locks, - * and the less traditional method of using mkdir() and rmdir(). - * There is no easy workaround. - * Any new method based on lockf() seemingly would be incompatible with - * the old methods; besides, lockf() is notoriously buggy under NFS. - * Since this problem afflicts scads of Unix programs, but is so rare - * that nobody seems to be worried about it, we won't worry either. - */ -# if !open_can_creat -# define create(f) creat(f, OPEN_CREAT_READONLY) -# else -# define create(f) open(f, OPEN_O_BINARY|OPEN_O_LOCK|OPEN_O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, OPEN_CREAT_READONLY) -# endif - - catchints(); - ignoreints(); - - /* - * Create a lock file for an RCS file. This should be atomic, i.e. - * if two processes try it simultaneously, at most one should succeed. - */ - seteid(); - fdesc = create(sp); - fdescSafer = fdSafer(fdesc); /* Do it now; setrid might use stderr. */ - e = errno; - setrid(); - - if (0 <= fdesc) - dirtpmaker[0] = effective; - - if (fdescSafer < 0) { - if (e == EACCES && stat(sp,&statbuf) == 0) - /* The RCS file is busy. */ - e = EEXIST; - } else { - e = ENOENT; - if (exists) { - f = Iopen(RCSpath, FOPEN_RB, status); - e = errno; - if (f && waslocked) { - /* Discard the previous lock in favor of this one. */ - ORCSclose(); - seteid(); - r = un_link(lockname); - e = errno; - setrid(); - if (r != 0) - enfaterror(e, lockname); - bufscpy(&dirtpname[lockdirtp_index], sp); - } - } - fdlock = fdescSafer; - } - - restoreints(); - - errno = e; - return f; -} - - void -keepdirtemp(name) - char const *name; -/* Do not unlink name, either because it's not there any more, - * or because it has already been unlinked. - */ -{ - register int i; - for (i=DIRTEMPNAMES; 0<=--i; ) - if (dirtpname[i].string == name) { - dirtpmaker[i] = notmade; - return; - } - faterror("keepdirtemp"); -} - - char const * -makedirtemp(isworkfile) - int isworkfile; -/* - * Create a unique pathname and store it into dirtpname. - * Because of storage in tpnames, dirtempunlink() can unlink the file later. - * Return a pointer to the pathname created. - * If ISWORKFILE is 1, put it into the working file's directory; - * if 0, put the unique file in RCSfile's directory. - */ -{ - register char *tp, *np; - register size_t dl; - register struct buf *bn; - register char const *name = isworkfile ? workname : RCSname; -# if has_mktemp - int fd; -# endif - - dl = basefilename(name) - name; - bn = &dirtpname[newRCSdirtp_index + isworkfile]; - bufalloc(bn, -# if has_mktemp - dl + 9 -# else - strlen(name) + 3 -# endif - ); - bufscpy(bn, name); - np = tp = bn->string; - tp += dl; - *tp++ = '_'; - *tp++ = '0'+isworkfile; - catchints(); -# if has_mktemp - VOID strcpy(tp, "XXXXXX"); - fd = mkstemp(np); - if (fd < 0 || !*np) - faterror("can't make temporary pathname `%.*s_%cXXXXXX'", - (int)dl, name, '0'+isworkfile - ); - close(fd); -# else - /* - * Posix 1003.1-1990 has no reliable way - * to create a unique file in a named directory. - * We fudge here. If the filename is abcde, - * the temp filename is _Ncde where N is a digit. - */ - name += dl; - if (*name) name++; - if (*name) name++; - VOID strcpy(tp, name); -# endif - dirtpmaker[newRCSdirtp_index + isworkfile] = real; - return np; -} - - void -dirtempunlink() -/* Clean up makedirtemp() files. May be invoked by signal handler. */ -{ - register int i; - enum maker m; - - for (i = DIRTEMPNAMES; 0 <= --i; ) - if ((m = dirtpmaker[i]) != notmade) { - if (m == effective) - seteid(); - VOID un_link(dirtpname[i].string); - if (m == effective) - setrid(); - dirtpmaker[i] = notmade; - } -} - - - int -#if has_prototypes -chnamemod( - FILE **fromp, char const *from, char const *to, - int set_mode, mode_t mode, time_t mtime -) - /* The `#if has_prototypes' is needed because mode_t might promote to int. */ -#else - chnamemod(fromp, from, to, set_mode, mode, mtime) - FILE **fromp; char const *from,*to; - int set_mode; mode_t mode; time_t mtime; -#endif -/* - * Rename a file (with stream pointer *FROMP) from FROM to TO. - * FROM already exists. - * If 0 < SET_MODE, change the mode to MODE, before renaming if possible. - * If MTIME is not -1, change its mtime to MTIME before renaming. - * Close and clear *FROMP before renaming it. - * Unlink TO if it already exists. - * Return -1 on error (setting errno), 0 otherwise. - */ -{ - mode_t mode_while_renaming = mode; - int fchmod_set_mode = 0; - -# if bad_a_rename || bad_NFS_rename - struct stat st; - if (bad_NFS_rename || (bad_a_rename && set_mode <= 0)) { - if (fstat(fileno(*fromp), &st) != 0) - return -1; - if (bad_a_rename && set_mode <= 0) - mode = st.st_mode; - } -# endif - -# if bad_a_rename - /* - * There's a short window of inconsistency - * during which the lock file is writable. - */ - mode_while_renaming = mode|S_IWUSR; - if (mode != mode_while_renaming) - set_mode = 1; -# endif - -# if has_fchmod - if (0<set_mode && fchmod(fileno(*fromp),mode_while_renaming) == 0) - fchmod_set_mode = set_mode; -# endif - /* If bad_chmod_close, we must close before chmod. */ - Ozclose(fromp); - if (fchmod_set_mode<set_mode && chmod(from, mode_while_renaming) != 0) - return -1; - - if (setmtime(from, mtime) != 0) - return -1; - -# if !has_rename || bad_b_rename - /* - * There's a short window of inconsistency - * during which TO does not exist. - */ - if (un_link(to) != 0 && errno != ENOENT) - return -1; -# endif - -# if has_rename - if (rename(from,to) != 0 && !(has_NFS && errno==ENOENT)) - return -1; -# else - if (do_link(from,to) != 0 || un_link(from) != 0) - return -1; -# endif - -# if bad_NFS_rename - { - /* - * Check whether the rename falsely reported success. - * A race condition can occur between the rename and the stat. - */ - struct stat tostat; - if (stat(to, &tostat) != 0) - return -1; - if (! same_file(st, tostat, 0)) { - errno = EIO; - return -1; - } - } -# endif - -# if bad_a_rename - if (0 < set_mode && chmod(to, mode) != 0) - return -1; -# endif - - return 0; -} - - int -setmtime(file, mtime) - char const *file; - time_t mtime; -/* Set FILE's last modified time to MTIME, but do nothing if MTIME is -1. */ -{ - static struct utimbuf amtime; /* static so unused fields are zero */ - if (mtime == -1) - return 0; - amtime.actime = now(); - amtime.modtime = mtime; - return utime(file, &amtime); -} - - - - int -findlock(delete, target) - int delete; - struct hshentry **target; -/* - * Find the first lock held by caller and return a pointer - * to the locked delta; also removes the lock if DELETE. - * If one lock, put it into *TARGET. - * Return 0 for no locks, 1 for one, 2 for two or more. - */ -{ - register struct rcslock *next, **trail, **found; - - found = 0; - for (trail = &Locks; (next = *trail); trail = &next->nextlock) - if (strcmp(getcaller(), next->login) == 0) { - if (found) { - rcserror("multiple revisions locked by %s; please specify one", getcaller()); - return 2; - } - found = trail; - } - if (!found) - return 0; - next = *found; - *target = next->delta; - if (delete) { - next->delta->lockedby = 0; - *found = next->nextlock; - } - return 1; -} - - int -addlock(delta, verbose) - struct hshentry * delta; - int verbose; -/* - * Add a lock held by caller to DELTA and yield 1 if successful. - * Print an error message if verbose and yield -1 if no lock is added because - * DELTA is locked by somebody other than caller. - * Return 0 if the caller already holds the lock. - */ -{ - register struct rcslock *next; - - for (next = Locks; next; next = next->nextlock) - if (cmpnum(delta->num, next->delta->num) == 0) - if (strcmp(getcaller(), next->login) == 0) - return 0; - else { - if (verbose) - rcserror("Revision %s is already locked by %s.", - delta->num, next->login - ); - return -1; - } - next = ftalloc(struct rcslock); - delta->lockedby = next->login = getcaller(); - next->delta = delta; - next->nextlock = Locks; - Locks = next; - return 1; -} - - - int -addsymbol(num, name, rebind) - char const *num, *name; - int rebind; -/* - * Associate with revision NUM the new symbolic NAME. - * If NAME already exists and REBIND is set, associate NAME with NUM; - * otherwise, print an error message and return false; - * Return -1 if unsuccessful, 0 if no change, 1 if change. - */ -{ - register struct assoc *next; - - for (next = Symbols; next; next = next->nextassoc) - if (strcmp(name, next->symbol) == 0) - if (strcmp(next->num,num) == 0) - return 0; - else if (rebind) { - next->num = num; - return 1; - } else { - rcserror("symbolic name %s already bound to %s", - name, next->num - ); - return -1; - } - next = ftalloc(struct assoc); - next->symbol = name; - next->num = num; - next->nextassoc = Symbols; - Symbols = next; - return 1; -} - - - - char const * -getcaller() -/* Get the caller's login name. */ -{ -# if has_setuid - return getusername(euid()!=ruid()); -# else - return getusername(false); -# endif -} - - - int -checkaccesslist() -/* - * Return true if caller is the superuser, the owner of the - * file, the access list is empty, or caller is on the access list. - * Otherwise, print an error message and return false. - */ -{ - register struct access const *next; - - if (!AccessList || myself(RCSstat.st_uid) || strcmp(getcaller(),"root")==0) - return true; - - next = AccessList; - do { - if (strcmp(getcaller(), next->login) == 0) - return true; - } while ((next = next->nextaccess)); - - rcserror("user %s not on the access list", getcaller()); - return false; -} - - - int -dorewrite(lockflag, changed) - int lockflag, changed; -/* - * Do nothing if LOCKFLAG is zero. - * Prepare to rewrite an RCS file if CHANGED is positive. - * Stop rewriting if CHANGED is zero, because there won't be any changes. - * Fail if CHANGED is negative. - * Return 0 on success, -1 on failure. - */ -{ - int r = 0, e; - - if (lockflag) - if (changed) { - if (changed < 0) - return -1; - putadmin(); - puttree(Head, frewrite); - aprintf(frewrite, "\n\n%s%c", Kdesc, nextc); - foutptr = frewrite; - } else { -# if bad_creat0 - int nr = !!frewrite, ne = 0; -# endif - ORCSclose(); - seteid(); - ignoreints(); -# if bad_creat0 - if (nr) { - nr = un_link(newRCSname); - ne = errno; - keepdirtemp(newRCSname); - } -# endif - r = un_link(lockname); - e = errno; - keepdirtemp(lockname); - restoreints(); - setrid(); - if (r != 0) - enerror(e, lockname); -# if bad_creat0 - if (nr != 0) { - enerror(ne, newRCSname); - r = -1; - } -# endif - } - return r; -} - - int -donerewrite(changed, newRCStime) - int changed; - time_t newRCStime; -/* - * Finish rewriting an RCS file if CHANGED is nonzero. - * Set its mode if CHANGED is positive. - * Set its modification time to NEWRCSTIME unless it is -1. - * Return 0 on success, -1 on failure. - */ -{ - int r = 0, e = 0; -# if bad_creat0 - int lr, le; -# endif - - if (changed && !nerror) { - if (finptr) { - fastcopy(finptr, frewrite); - Izclose(&finptr); - } - if (1 < RCSstat.st_nlink) - rcswarn("breaking hard link"); - aflush(frewrite); - seteid(); - ignoreints(); - r = chnamemod( - &frewrite, newRCSname, RCSname, changed, - RCSstat.st_mode & (mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH), - newRCStime - ); - e = errno; - keepdirtemp(newRCSname); -# if bad_creat0 - lr = un_link(lockname); - le = errno; - keepdirtemp(lockname); -# endif - restoreints(); - setrid(); - if (r != 0) { - enerror(e, RCSname); - error("saved in %s", newRCSname); - } -# if bad_creat0 - if (lr != 0) { - enerror(le, lockname); - r = -1; - } -# endif - } - return r; -} - - void -ORCSclose() -{ - if (0 <= fdlock) { - if (close(fdlock) != 0) - efaterror(lockname); - fdlock = -1; - } - Ozclose(&frewrite); -} - - void -ORCSerror() -/* -* Like ORCSclose, except we are cleaning up after an interrupt or fatal error. -* Do not report errors, since this may loop. This is needed only because -* some brain-damaged hosts (e.g. OS/2) cannot unlink files that are open, and -* some nearly-Posix hosts (e.g. NFS) work better if the files are closed first. -* This isn't a completely reliable away to work around brain-damaged hosts, -* because of the gap between actual file opening and setting frewrite etc., -* but it's better than nothing. -*/ -{ - if (0 <= fdlock) - VOID close(fdlock); - if (frewrite) - /* Avoid fclose, since stdio may not be reentrant. */ - VOID close(fileno(frewrite)); -} diff --git a/gnu/usr.bin/rcs/lib/rcsfcmp.c b/gnu/usr.bin/rcs/lib/rcsfcmp.c deleted file mode 100644 index ef05290..0000000 --- a/gnu/usr.bin/rcs/lib/rcsfcmp.c +++ /dev/null @@ -1,354 +0,0 @@ -/* Compare working files, ignoring RCS keyword strings. */ - -/***************************************************************************** - * rcsfcmp() - * Testprogram: define FCMPTEST - ***************************************************************************** - */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - - - - - -/* - * Revision 5.14 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.13 1995/06/01 16:23:43 eggert - * (rcsfcmp): Add -kb support. - * - * Revision 5.12 1994/03/17 14:05:48 eggert - * Normally calculate the $Log prefix from context, not from RCS file. - * Calculate line numbers correctly even if the $Log prefix contains newlines. - * Remove lint. - * - * Revision 5.11 1993/11/03 17:42:27 eggert - * Fix yet another off-by-one error when comparing Log string expansions. - * - * Revision 5.10 1992/07/28 16:12:44 eggert - * Statement macro names now end in _. - * - * Revision 5.9 1991/10/07 17:32:46 eggert - * Count log lines correctly. - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Tune. - * - * Revision 5.7 1991/04/21 11:58:22 eggert - * Fix errno bug. Add MS-DOS support. - * - * Revision 5.6 1991/02/28 19:18:47 eggert - * Open work file at most once. - * - * Revision 5.5 1990/11/27 09:26:05 eggert - * Fix comment leader bug. - * - * Revision 5.4 1990/11/01 05:03:42 eggert - * Permit arbitrary data in logs and comment leaders. - * - * Revision 5.3 1990/09/11 02:41:15 eggert - * Don't ignore differences inside keyword strings if -ko is set. - * - * Revision 5.1 1990/08/29 07:13:58 eggert - * Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:12:49 eggert - * Don't append "checked in with -k by " log to logs, - * so that checking in a program with -k doesn't change it. - * Ansify and Posixate. Remove lint. - * - * Revision 4.5 89/05/01 15:12:42 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.4 88/08/09 19:12:50 eggert - * Shrink stdio code size. - * - * Revision 4.3 87/12/18 11:40:02 narten - * lint cleanups (Guy Harris) - * - * Revision 4.2 87/10/18 10:33:06 narten - * updting version number. Changes relative to 1.1 actually relative to - * 4.1 - * - * Revision 1.2 87/03/27 14:22:19 jenkins - * Port to suns - * - * Revision 4.1 83/05/10 16:24:04 wft - * Marker matching now uses trymatch(). Marker pattern is now - * checked precisely. - * - * Revision 3.1 82/12/04 13:21:40 wft - * Initial revision. - * - */ - -/* -#define FCMPTEST -*/ -/* Testprogram; prints out whether two files are identical, - * except for keywords - */ - -#include "rcsbase.h" - -libId(fcmpId, "$FreeBSD$") - - static int discardkeyval P((int,RILE*)); - static int -discardkeyval(c, f) - register int c; - register RILE *f; -{ - for (;;) - switch (c) { - case KDELIM: - case '\n': - return c; - default: - Igeteof_(f, c, return EOF;) - break; - } -} - - int -rcsfcmp(xfp, xstatp, uname, delta) - register RILE *xfp; - struct stat const *xstatp; - char const *uname; - struct hshentry const *delta; -/* Compare the files xfp and uname. Return zero - * if xfp has the same contents as uname and neither has keywords, - * otherwise -1 if they are the same ignoring keyword values, - * and 1 if they differ even ignoring - * keyword values. For the LOG-keyword, rcsfcmp skips the log message - * given by the parameter delta in xfp. Thus, rcsfcmp returns nonpositive - * if xfp contains the same as uname, with the keywords expanded. - * Implementation: character-by-character comparison until $ is found. - * If a $ is found, read in the marker keywords; if they are real keywords - * and identical, read in keyword value. If value is terminated properly, - * disregard it and optionally skip log message; otherwise, compare value. - */ -{ - register int xc, uc; - char xkeyword[keylength+2]; - int eqkeyvals; - register RILE *ufp; - register int xeof, ueof; - register char * tp; - register char const *sp; - register size_t leaderlen; - int result; - enum markers match1; - struct stat ustat; - - if (!(ufp = Iopen(uname, FOPEN_R_WORK, &ustat))) { - efaterror(uname); - } - xeof = ueof = false; - if (MIN_UNEXPAND <= Expand) { - if (!(result = xstatp->st_size!=ustat.st_size)) { -# if large_memory && maps_memory - result = !!memcmp(xfp->base,ufp->base,(size_t)xstatp->st_size); -# else - for (;;) { - /* get the next characters */ - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - if (xc != uc) - goto return1; - } -# endif - } - } else { - xc = 0; - uc = 0; /* Keep lint happy. */ - leaderlen = 0; - result = 0; - - for (;;) { - if (xc != KDELIM) { - /* get the next characters */ - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - } else { - /* try to get both keywords */ - tp = xkeyword; - for (;;) { - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - if (xc != uc) - break; - switch (xc) { - default: - if (xkeyword+keylength <= tp) - break; - *tp++ = xc; - continue; - case '\n': case KDELIM: case VDELIM: - break; - } - break; - } - if ( - (xc==KDELIM || xc==VDELIM) && (uc==KDELIM || uc==VDELIM) && - (*tp = xc, (match1 = trymatch(xkeyword)) != Nomatch) - ) { -#ifdef FCMPTEST - VOID printf("found common keyword %s\n",xkeyword); -#endif - result = -1; - for (;;) { - if (xc != uc) { - xc = discardkeyval(xc, xfp); - uc = discardkeyval(uc, ufp); - if ((xeof = xc==EOF) | (ueof = uc==EOF)) - goto eof; - eqkeyvals = false; - break; - } - switch (xc) { - default: - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - continue; - - case '\n': case KDELIM: - eqkeyvals = true; - break; - } - break; - } - if (xc != uc) - goto return1; - if (xc==KDELIM) { - /* Skip closing KDELIM. */ - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - /* if the keyword is LOG, also skip the log message in xfp*/ - if (match1==Log) { - /* first, compute the number of line feeds in log msg */ - int lncnt; - size_t ls, ccnt; - sp = delta->log.string; - ls = delta->log.size; - if (ls<sizeof(ciklog)-1 || memcmp(sp,ciklog,sizeof(ciklog)-1)) { - /* - * This log message was inserted. Skip its header. - * The number of newlines to skip is - * 1 + (C+1)*(1+L+1), where C is the number of newlines - * in the comment leader, and L is the number of - * newlines in the log string. - */ - int c1 = 1; - for (ccnt=Comment.size; ccnt--; ) - c1 += Comment.string[ccnt] == '\n'; - lncnt = 2*c1 + 1; - while (ls--) if (*sp++=='\n') lncnt += c1; - for (;;) { - if (xc=='\n') - if(--lncnt==0) break; - Igeteof_(xfp, xc, goto returnresult;) - } - /* skip last comment leader */ - /* Can't just skip another line here, because there may be */ - /* additional characters on the line (after the Log....$) */ - ccnt = RCSversion<VERSION(5) ? Comment.size : leaderlen; - do { - Igeteof_(xfp, xc, goto returnresult;) - /* - * Read to the end of the comment leader or '\n', - * whatever comes first, because the leader's - * trailing white space was probably stripped. - */ - } while (ccnt-- && (xc!='\n' || --c1)); - } - } - } else { - /* both end in the same character, but not a KDELIM */ - /* must compare string values.*/ -#ifdef FCMPTEST - VOID printf("non-terminated keywords %s, potentially different values\n",xkeyword); -#endif - if (!eqkeyvals) - goto return1; - } - } - } - if (xc != uc) - goto return1; - if (xc == '\n') - leaderlen = 0; - else - leaderlen++; - } - } - - eof: - if (xeof==ueof) - goto returnresult; - return1: - result = 1; - returnresult: - Ifclose(ufp); - return result; -} - - - -#ifdef FCMPTEST - -char const cmdid[] = "rcsfcmp"; - -main(argc, argv) -int argc; char *argv[]; -/* first argument: comment leader; 2nd: log message, 3rd: expanded file, - * 4th: unexpanded file - */ -{ struct hshentry delta; - - Comment.string = argv[1]; - Comment.size = strlen(argv[1]); - delta.log.string = argv[2]; - delta.log.size = strlen(argv[2]); - if (rcsfcmp(Iopen(argv[3], FOPEN_R_WORK, (struct stat*)0), argv[4], &delta)) - VOID printf("files are the same\n"); - else VOID printf("files are different\n"); -} -#endif diff --git a/gnu/usr.bin/rcs/lib/rcsfnms.c b/gnu/usr.bin/rcs/lib/rcsfnms.c deleted file mode 100644 index 00caec5..0000000 --- a/gnu/usr.bin/rcs/lib/rcsfnms.c +++ /dev/null @@ -1,1132 +0,0 @@ -/* RCS filename and pathname handling */ - -/**************************************************************************** - * creation and deletion of /tmp temporaries - * pairing of RCS pathnames and working pathnames. - * Testprogram: define PAIRTEST - **************************************************************************** - */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - - - - -/* - * Revision 5.16 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.15 1995/06/01 16:23:43 eggert - * (basefilename): Renamed from basename to avoid collisions. - * (dirlen): Remove (for similar reasons). - * (rcsreadopen): Open with FOPEN_RB. - * (SLASHSLASH_is_SLASH): Default is 0. - * (getcwd): Work around bad_wait_if_SIGCHLD_ignored bug. - * - * Revision 5.14 1994/03/17 14:05:48 eggert - * Strip trailing SLASHes from TMPDIR; some systems need this. Remove lint. - * - * Revision 5.13 1993/11/03 17:42:27 eggert - * Determine whether a file name is too long indirectly, - * by examining inode numbers, instead of trying to use operating system - * primitives like pathconf, which are not trustworthy in general. - * File names may now hold white space or $. - * Do not flatten ../X in pathnames; that may yield wrong answer for symlinks. - * Add getabsname hook. Improve quality of diagnostics. - * - * Revision 5.12 1992/07/28 16:12:44 eggert - * Add .sty. .pl now implies Perl, not Prolog. Fix fdlock initialization bug. - * Check that $PWD is really ".". Be consistent about pathnames vs filenames. - * - * Revision 5.11 1992/02/17 23:02:25 eggert - * `a/RCS/b/c' is now an RCS file with an empty extension, not just `a/b/RCS/c'. - * - * Revision 5.10 1992/01/24 18:44:19 eggert - * Fix bug: Expand and Ignored weren't reinitialized. - * Avoid `char const c=ch;' compiler bug. - * Add support for bad_creat0. - * - * Revision 5.9 1992/01/06 02:42:34 eggert - * Shorten long (>31 chars) name. - * while (E) ; -> while (E) continue; - * - * Revision 5.8 1991/09/24 00:28:40 eggert - * Don't export bindex(). - * - * Revision 5.7 1991/08/19 03:13:55 eggert - * Fix messages when rcswriteopen fails. - * Look in $TMP and $TEMP if $TMPDIR isn't set. Tune. - * - * Revision 5.6 1991/04/21 11:58:23 eggert - * Fix errno bugs. Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.5 1991/02/26 17:48:38 eggert - * Fix setuid bug. Support new link behavior. - * Define more portable getcwd(). - * - * Revision 5.4 1990/11/01 05:03:43 eggert - * Permit arbitrary data in comment leaders. - * - * Revision 5.3 1990/09/14 22:56:16 hammer - * added more filename extensions and their comment leaders - * - * Revision 5.2 1990/09/04 08:02:23 eggert - * Fix typo when !RCSSEP. - * - * Revision 5.1 1990/08/29 07:13:59 eggert - * Work around buggy compilers with defective argument promotion. - * - * Revision 5.0 1990/08/22 08:12:50 eggert - * Ignore signals when manipulating the semaphore file. - * Modernize list of filename extensions. - * Permit paths of arbitrary length. Beware filenames beginning with "-". - * Remove compile-time limits; use malloc instead. - * Permit dates past 1999/12/31. Make lock and temp files faster and safer. - * Ansify and Posixate. - * Don't use access(). Fix test for non-regular files. Tune. - * - * Revision 4.8 89/05/01 15:09:41 narten - * changed getwd to not stat empty directories. - * - * Revision 4.7 88/08/09 19:12:53 eggert - * Fix troff macro comment leader bug; add Prolog; allow cc -R; remove lint. - * - * Revision 4.6 87/12/18 11:40:23 narten - * additional file types added from 4.3 BSD version, and SPARC assembler - * comment character added. Also, more lint cleanups. (Guy Harris) - * - * Revision 4.5 87/10/18 10:34:16 narten - * Updating version numbers. Changes relative to 1.1 actually relative - * to verion 4.3 - * - * Revision 1.3 87/03/27 14:22:21 jenkins - * Port to suns - * - * Revision 1.2 85/06/26 07:34:28 svb - * Comment leader '% ' for '*.tex' files added. - * - * Revision 4.3 83/12/15 12:26:48 wft - * Added check for KDELIM in filenames to pairfilenames(). - * - * Revision 4.2 83/12/02 22:47:45 wft - * Added csh, red, and sl filename suffixes. - * - * Revision 4.1 83/05/11 16:23:39 wft - * Added initialization of Dbranch to InitAdmin(). Canged pairfilenames(): - * 1. added copying of path from workfile to RCS file, if RCS file is omitted; - * 2. added getting the file status of RCS and working files; - * 3. added ignoring of directories. - * - * Revision 3.7 83/05/11 15:01:58 wft - * Added comtable[] which pairs filename suffixes with comment leaders; - * updated InitAdmin() accordingly. - * - * Revision 3.6 83/04/05 14:47:36 wft - * fixed Suffix in InitAdmin(). - * - * Revision 3.5 83/01/17 18:01:04 wft - * Added getwd() and rename(); these can be removed by defining - * V4_2BSD, since they are not needed in 4.2 bsd. - * Changed sys/param.h to sys/types.h. - * - * Revision 3.4 82/12/08 21:55:20 wft - * removed unused variable. - * - * Revision 3.3 82/11/28 20:31:37 wft - * Changed mktempfile() to store the generated filenames. - * Changed getfullRCSname() to store the file and pathname, and to - * delete leading "../" and "./". - * - * Revision 3.2 82/11/12 14:29:40 wft - * changed pairfilenames() to handle file.sfx,v; also deleted checkpathnosfx(), - * checksuffix(), checkfullpath(). Semaphore name generation updated. - * mktempfile() now checks for nil path; freefilename initialized properly. - * Added Suffix .h to InitAdmin. Added testprogram PAIRTEST. - * Moved rmsema, trysema, trydiraccess, getfullRCSname from rcsutil.c to here. - * - * Revision 3.1 82/10/18 14:51:28 wft - * InitAdmin() now initializes StrictLocks=STRICT_LOCKING (def. in rcsbase.h). - * renamed checkpath() to checkfullpath(). - */ - - -#include "rcsbase.h" - -libId(fnmsId, "$FreeBSD$") - -static char const *bindex P((char const*,int)); -static int fin2open P((char const*, size_t, char const*, size_t, char const*, size_t, RILE*(*)P((struct buf*,struct stat*,int)), int)); -static int finopen P((RILE*(*)P((struct buf*,struct stat*,int)), int)); -static int suffix_matches P((char const*,char const*)); -static size_t dir_useful_len P((char const*)); -static size_t suffixlen P((char const*)); -static void InitAdmin P((void)); - -char const *RCSname; -char *workname; -int fdlock; -FILE *workstdout; -struct stat RCSstat; -char const *suffixes; - -static char const rcsdir[] = "RCS"; -#define rcslen (sizeof(rcsdir)-1) - -static struct buf RCSbuf, RCSb; -static int RCSerrno; - - -/* Temp names to be unlinked when done, if they are not 0. */ -#define TEMPNAMES 5 /* must be at least DIRTEMPNAMES (see rcsedit.c) */ -static char *volatile tpnames[TEMPNAMES]; - - -struct compair { - char const *suffix, *comlead; -}; - -/* -* This table is present only for backwards compatibility. -* Normally we ignore this table, and use the prefix of the `$Log' line instead. -*/ -static struct compair const comtable[] = { - { "a" , "-- " }, /* Ada */ - { "ada" , "-- " }, - { "adb" , "-- " }, - { "ads" , "-- " }, - { "asm" , ";; " }, /* assembler (MS-DOS) */ - { "bat" , ":: " }, /* batch (MS-DOS) */ - { "body", "-- " }, /* Ada */ - { "c" , " * " }, /* C */ - { "c++" , "// " }, /* C++ in all its infinite guises */ - { "cc" , "// " }, - { "cpp" , "// " }, - { "cxx" , "// " }, - { "cl" , ";;; "}, /* Common Lisp */ - { "cmd" , ":: " }, /* command (OS/2) */ - { "cmf" , "c " }, /* CM Fortran */ - { "cs" , " * " }, /* C* */ - { "el" , "; " }, /* Emacs Lisp */ - { "f" , "c " }, /* Fortran */ - { "for" , "c " }, - { "h" , " * " }, /* C-header */ - { "hpp" , "// " }, /* C++ header */ - { "hxx" , "// " }, - { "l" , " * " }, /* lex (NOTE: franzlisp disagrees) */ - { "lisp", ";;; "}, /* Lucid Lisp */ - { "lsp" , ";; " }, /* Microsoft Lisp */ - { "m" , "// " }, /* Objective C */ - { "mac" , ";; " }, /* macro (DEC-10, MS-DOS, PDP-11, VMS, etc) */ - { "me" , ".\\\" "}, /* troff -me */ - { "ml" , "; " }, /* mocklisp */ - { "mm" , ".\\\" "}, /* troff -mm */ - { "ms" , ".\\\" "}, /* troff -ms */ - { "p" , " * " }, /* Pascal */ - { "pas" , " * " }, - { "ps" , "% " }, /* PostScript */ - { "spec", "-- " }, /* Ada */ - { "sty" , "% " }, /* LaTeX style */ - { "tex" , "% " }, /* TeX */ - { "y" , " * " }, /* yacc */ - { 0 , "# " } /* default for unknown suffix; must be last */ -}; - -#if has_mktemp - static char const *tmp P((void)); - static char const * -tmp() -/* Yield the name of the tmp directory. */ -{ - static char const *s; - if (!s - && !(s = cgetenv("TMPDIR")) /* Unix tradition */ - && !(s = cgetenv("TMP")) /* DOS tradition */ - && !(s = cgetenv("TEMP")) /* another DOS tradition */ - ) - s = TMPDIR; - return s; -} -#endif - - char const * -maketemp(n) - int n; -/* Create a unique pathname using n and the process id and store it - * into the nth slot in tpnames. - * Because of storage in tpnames, tempunlink() can unlink the file later. - * Return a pointer to the pathname created. - */ -{ - char *p; - char const *t = tpnames[n]; -# if has_mktemp - int fd; -# endif - - if (t) - return t; - - catchints(); - { -# if has_mktemp - char const *tp = tmp(); - size_t tplen = dir_useful_len(tp); - p = testalloc(tplen + 10); - VOID sprintf(p, "%.*s%cT%cXXXXXX", (int)tplen, tp, SLASH, '0'+n); - fd = mkstemp(p); - if (fd < 0 || !*p) - faterror("can't make temporary pathname `%.*s%cT%cXXXXXX'", - (int)tplen, tp, SLASH, '0'+n - ); - close(fd); -# else - static char tpnamebuf[TEMPNAMES][L_tmpnam]; - p = tpnamebuf[n]; - if (!tmpnam(p) || !*p) -# ifdef P_tmpdir - faterror("can't make temporary pathname `%s...'",P_tmpdir); -# else - faterror("can't make temporary pathname"); -# endif -# endif - } - - tpnames[n] = p; - return p; -} - - void -tempunlink() -/* Clean up maketemp() files. May be invoked by signal handler. - */ -{ - register int i; - register char *p; - - for (i = TEMPNAMES; 0 <= --i; ) - if ((p = tpnames[i])) { - VOID unlink(p); - /* - * We would tfree(p) here, - * but this might dump core if we're handing a signal. - * We're about to exit anyway, so we won't bother. - */ - tpnames[i] = 0; - } -} - - - static char const * -bindex(sp, c) - register char const *sp; - register int c; -/* Function: Finds the last occurrence of character c in string sp - * and returns a pointer to the character just beyond it. If the - * character doesn't occur in the string, sp is returned. - */ -{ - register char const *r; - r = sp; - while (*sp) { - if (*sp++ == c) r=sp; - } - return r; -} - - - - static int -suffix_matches(suffix, pattern) - register char const *suffix, *pattern; -{ - register int c; - if (!pattern) - return true; - for (;;) - switch (*suffix++ - (c = *pattern++)) { - case 0: - if (!c) - return true; - break; - - case 'A'-'a': - if (ctab[c] == Letter) - break; - /* fall into */ - default: - return false; - } -} - - - static void -InitAdmin() -/* function: initializes an admin node */ -{ - register char const *Suffix; - register int i; - - Head=0; Dbranch=0; AccessList=0; Symbols=0; Locks=0; - StrictLocks=STRICT_LOCKING; - - /* guess the comment leader from the suffix*/ - Suffix = bindex(workname, '.'); - if (Suffix==workname) Suffix= ""; /* empty suffix; will get default*/ - for (i=0; !suffix_matches(Suffix,comtable[i].suffix); i++) - continue; - Comment.string = comtable[i].comlead; - Comment.size = strlen(comtable[i].comlead); - Expand = KEYVAL_EXPAND; - clear_buf(&Ignored); - Lexinit(); /* note: if !finptr, reads nothing; only initializes */ -} - - - - void -bufalloc(b, size) - register struct buf *b; - size_t size; -/* Ensure *B is a name buffer of at least SIZE bytes. - * *B's old contents can be freed; *B's new contents are undefined. - */ -{ - if (b->size < size) { - if (b->size) - tfree(b->string); - else - b->size = sizeof(malloc_type); - while (b->size < size) - b->size <<= 1; - b->string = tnalloc(char, b->size); - } -} - - void -bufrealloc(b, size) - register struct buf *b; - size_t size; -/* like bufalloc, except *B's old contents, if any, are preserved */ -{ - if (b->size < size) { - if (!b->size) - bufalloc(b, size); - else { - while ((b->size <<= 1) < size) - continue; - b->string = trealloc(char, b->string, b->size); - } - } -} - - void -bufautoend(b) - struct buf *b; -/* Free an auto buffer at block exit. */ -{ - if (b->size) - tfree(b->string); -} - - struct cbuf -bufremember(b, s) - struct buf *b; - size_t s; -/* - * Free the buffer B with used size S. - * Yield a cbuf with identical contents. - * The cbuf will be reclaimed when this input file is finished. - */ -{ - struct cbuf cb; - - if ((cb.size = s)) - cb.string = fremember(trealloc(char, b->string, s)); - else { - bufautoend(b); /* not really auto */ - cb.string = ""; - } - return cb; -} - - char * -bufenlarge(b, alim) - register struct buf *b; - char const **alim; -/* Make *B larger. Set *ALIM to its new limit, and yield the relocated value - * of its old limit. - */ -{ - size_t s = b->size; - bufrealloc(b, s + 1); - *alim = b->string + b->size; - return b->string + s; -} - - void -bufscat(b, s) - struct buf *b; - char const *s; -/* Concatenate S to B's end. */ -{ - size_t blen = b->string ? strlen(b->string) : 0; - bufrealloc(b, blen+strlen(s)+1); - VOID strcpy(b->string+blen, s); -} - - void -bufscpy(b, s) - struct buf *b; - char const *s; -/* Copy S into B. */ -{ - bufalloc(b, strlen(s)+1); - VOID strcpy(b->string, s); -} - - - char const * -basefilename(p) - char const *p; -/* Yield the address of the base filename of the pathname P. */ -{ - register char const *b = p, *q = p; - for (;;) - switch (*q++) { - case SLASHes: b = q; break; - case 0: return b; - } -} - - - static size_t -suffixlen(x) - char const *x; -/* Yield the length of X, an RCS pathname suffix. */ -{ - register char const *p; - - p = x; - for (;;) - switch (*p) { - case 0: case SLASHes: - return p - x; - - default: - ++p; - continue; - } -} - - char const * -rcssuffix(name) - char const *name; -/* Yield the suffix of NAME if it is an RCS pathname, 0 otherwise. */ -{ - char const *x, *p, *nz; - size_t nl, xl; - - nl = strlen(name); - nz = name + nl; - x = suffixes; - do { - if ((xl = suffixlen(x))) { - if (xl <= nl && memcmp(p = nz-xl, x, xl) == 0) - return p; - } else - for (p = name; p < nz - rcslen; p++) - if ( - isSLASH(p[rcslen]) - && (p==name || isSLASH(p[-1])) - && memcmp(p, rcsdir, rcslen) == 0 - ) - return nz; - x += xl; - } while (*x++); - return 0; -} - - /*ARGSUSED*/ RILE * -rcsreadopen(RCSpath, status, mustread) - struct buf *RCSpath; - struct stat *status; - int mustread; -/* Open RCSPATH for reading and yield its FILE* descriptor. - * If successful, set *STATUS to its status. - * Pass this routine to pairnames() for read-only access to the file. */ -{ - return Iopen(RCSpath->string, FOPEN_RB, status); -} - - static int -finopen(rcsopen, mustread) - RILE *(*rcsopen)P((struct buf*,struct stat*,int)); - int mustread; -/* - * Use RCSOPEN to open an RCS file; MUSTREAD is set if the file must be read. - * Set finptr to the result and yield true if successful. - * RCSb holds the file's name. - * Set RCSbuf to the best RCS name found so far, and RCSerrno to its errno. - * Yield true if successful or if an unusual failure. - */ -{ - int interesting, preferold; - - /* - * We prefer an old name to that of a nonexisting new RCS file, - * unless we tried locking the old name and failed. - */ - preferold = RCSbuf.string[0] && (mustread||0<=fdlock); - - finptr = (*rcsopen)(&RCSb, &RCSstat, mustread); - interesting = finptr || errno!=ENOENT; - if (interesting || !preferold) { - /* Use the new name. */ - RCSerrno = errno; - bufscpy(&RCSbuf, RCSb.string); - } - return interesting; -} - - static int -fin2open(d, dlen, base, baselen, x, xlen, rcsopen, mustread) - char const *d, *base, *x; - size_t dlen, baselen, xlen; - RILE *(*rcsopen)P((struct buf*,struct stat*,int)); - int mustread; -/* - * D is a directory name with length DLEN (including trailing slash). - * BASE is a filename with length BASELEN. - * X is an RCS pathname suffix with length XLEN. - * Use RCSOPEN to open an RCS file; MUSTREAD is set if the file must be read. - * Yield true if successful. - * Try dRCS/basex first; if that fails and x is nonempty, try dbasex. - * Put these potential names in RCSb. - * Set RCSbuf to the best RCS name found so far, and RCSerrno to its errno. - * Yield true if successful or if an unusual failure. - */ -{ - register char *p; - - bufalloc(&RCSb, dlen + rcslen + 1 + baselen + xlen + 1); - - /* Try dRCS/basex. */ - VOID memcpy(p = RCSb.string, d, dlen); - VOID memcpy(p += dlen, rcsdir, rcslen); - p += rcslen; - *p++ = SLASH; - VOID memcpy(p, base, baselen); - VOID memcpy(p += baselen, x, xlen); - p[xlen] = 0; - if (xlen) { - if (finopen(rcsopen, mustread)) - return true; - - /* Try dbasex. */ - /* Start from scratch, because finopen() may have changed RCSb. */ - VOID memcpy(p = RCSb.string, d, dlen); - VOID memcpy(p += dlen, base, baselen); - VOID memcpy(p += baselen, x, xlen); - p[xlen] = 0; - } - return finopen(rcsopen, mustread); -} - - int -pairnames(argc, argv, rcsopen, mustread, quiet) - int argc; - char **argv; - RILE *(*rcsopen)P((struct buf*,struct stat*,int)); - int mustread, quiet; -/* - * Pair the pathnames pointed to by argv; argc indicates - * how many there are. - * Place a pointer to the RCS pathname into RCSname, - * and a pointer to the pathname of the working file into workname. - * If both are given, and workstdout - * is set, a warning is printed. - * - * If the RCS file exists, places its status into RCSstat. - * - * If the RCS file exists, it is RCSOPENed for reading, the file pointer - * is placed into finptr, and the admin-node is read in; returns 1. - * If the RCS file does not exist and MUSTREAD, - * print an error unless QUIET and return 0. - * Otherwise, initialize the admin node and return -1. - * - * 0 is returned on all errors, e.g. files that are not regular files. - */ -{ - static struct buf tempbuf; - - register char *p, *arg, *RCS1; - char const *base, *RCSbase, *x; - int paired; - size_t arglen, dlen, baselen, xlen; - - fdlock = -1; - - if (!(arg = *argv)) return 0; /* already paired pathname */ - if (*arg == '-') { - error("%s option is ignored after pathnames", arg); - return 0; - } - - base = basefilename(arg); - paired = false; - - /* first check suffix to see whether it is an RCS file or not */ - if ((x = rcssuffix(arg))) - { - /* RCS pathname given */ - RCS1 = arg; - RCSbase = base; - baselen = x - base; - if ( - 1 < argc && - !rcssuffix(workname = p = argv[1]) && - baselen <= (arglen = strlen(p)) && - ((p+=arglen-baselen) == workname || isSLASH(p[-1])) && - memcmp(base, p, baselen) == 0 - ) { - argv[1] = 0; - paired = true; - } else { - bufscpy(&tempbuf, base); - workname = p = tempbuf.string; - p[baselen] = 0; - } - } else { - /* working file given; now try to find RCS file */ - workname = arg; - baselen = strlen(base); - /* Derive RCS pathname. */ - if ( - 1 < argc && - (x = rcssuffix(RCS1 = argv[1])) && - baselen <= x - RCS1 && - ((RCSbase=x-baselen)==RCS1 || isSLASH(RCSbase[-1])) && - memcmp(base, RCSbase, baselen) == 0 - ) { - argv[1] = 0; - paired = true; - } else - RCSbase = RCS1 = 0; - } - /* Now we have a (tentative) RCS pathname in RCS1 and workname. */ - /* Second, try to find the right RCS file */ - if (RCSbase!=RCS1) { - /* a path for RCSfile is given; single RCS file to look for */ - bufscpy(&RCSbuf, RCS1); - finptr = (*rcsopen)(&RCSbuf, &RCSstat, mustread); - RCSerrno = errno; - } else { - bufscpy(&RCSbuf, ""); - if (RCS1) - /* RCS filename was given without path. */ - VOID fin2open(arg, (size_t)0, RCSbase, baselen, - x, strlen(x), rcsopen, mustread - ); - else { - /* No RCS pathname was given. */ - /* Try each suffix in turn. */ - dlen = base-arg; - x = suffixes; - while (! fin2open(arg, dlen, base, baselen, - x, xlen=suffixlen(x), rcsopen, mustread - )) { - x += xlen; - if (!*x++) - break; - } - } - } - RCSname = p = RCSbuf.string; - if (finptr) { - if (!S_ISREG(RCSstat.st_mode)) { - error("%s isn't a regular file -- ignored", p); - return 0; - } - Lexinit(); getadmin(); - } else { - if (RCSerrno!=ENOENT || mustread || fdlock<0) { - if (RCSerrno == EEXIST) - error("RCS file %s is in use", p); - else if (!quiet || RCSerrno!=ENOENT) - enerror(RCSerrno, p); - return 0; - } - InitAdmin(); - }; - - if (paired && workstdout) - workwarn("Working file ignored due to -p option"); - - prevkeys = false; - return finptr ? 1 : -1; -} - - - char const * -getfullRCSname() -/* - * Return a pointer to the full pathname of the RCS file. - * Remove leading `./'. - */ -{ - if (ROOTPATH(RCSname)) { - return RCSname; - } else { - static struct buf rcsbuf; -# if needs_getabsname - bufalloc(&rcsbuf, SIZEABLE_PATH + 1); - while (getabsname(RCSname, rcsbuf.string, rcsbuf.size) != 0) - if (errno == ERANGE) - bufalloc(&rcsbuf, rcsbuf.size<<1); - else - efaterror("getabsname"); -# else - static char const *wdptr; - static struct buf wdbuf; - static size_t wdlen; - - register char const *r; - register size_t dlen; - register char *d; - register char const *wd; - - if (!(wd = wdptr)) { - /* Get working directory for the first time. */ - char *PWD = cgetenv("PWD"); - struct stat PWDstat, dotstat; - if (! ( - (d = PWD) && - ROOTPATH(PWD) && - stat(PWD, &PWDstat) == 0 && - stat(".", &dotstat) == 0 && - same_file(PWDstat, dotstat, 1) - )) { - bufalloc(&wdbuf, SIZEABLE_PATH + 1); -# if has_getcwd || !has_getwd - while (!(d = getcwd(wdbuf.string, wdbuf.size))) - if (errno == ERANGE) - bufalloc(&wdbuf, wdbuf.size<<1); - else if ((d = PWD)) - break; - else - efaterror("getcwd"); -# else - d = getwd(wdbuf.string); - if (!d && !(d = PWD)) - efaterror("getwd"); -# endif - } - wdlen = dir_useful_len(d); - d[wdlen] = 0; - wdptr = wd = d; - } - /* - * Remove leading `./'s from RCSname. - * Do not try to handle `../', since removing it may yield - * the wrong answer in the presence of symbolic links. - */ - for (r = RCSname; r[0]=='.' && isSLASH(r[1]); r += 2) - /* `.////' is equivalent to `./'. */ - while (isSLASH(r[2])) - r++; - /* Build full pathname. */ - dlen = wdlen; - bufalloc(&rcsbuf, dlen + strlen(r) + 2); - d = rcsbuf.string; - VOID memcpy(d, wd, dlen); - d += dlen; - *d++ = SLASH; - VOID strcpy(d, r); -# endif - return rcsbuf.string; - } -} - -/* Derived from code from the XFree86 project */ - char const * -getfullCVSname() -/* Function: returns a pointer to the path name of the RCS file with the - * CVSROOT part stripped off, and with 'Attic/' stripped off (if present). - */ -{ - -#define ATTICDIR "/Attic" - - char const *namebuf = getfullRCSname(); - char *cvsroot = cgetenv("CVSROOT"); - int cvsrootlen; - char *c = NULL; - int alen = strlen(ATTICDIR); - - if ((c = strrchr(namebuf, '/')) != NULL) { - if (namebuf - c >= alen) { - if (!strncmp(c - alen, ATTICDIR, alen)) { - while(*c != '\0') { - *(c - alen) = *c; - c++; - } - *(c - alen) = '\0'; - } - } - } - - if (!cvsroot) - return(namebuf); - else - { - cvsrootlen = strlen(cvsroot); - if (!strncmp(namebuf, cvsroot, cvsrootlen) && - namebuf[cvsrootlen] == '/') - return(namebuf + cvsrootlen + 1); - else - return(namebuf); - } -} - - static size_t -dir_useful_len(d) - char const *d; -/* -* D names a directory; yield the number of characters of D's useful part. -* To create a file in D, append a SLASH and a file name to D's useful part. -* Ignore trailing slashes if possible; not only are they ugly, -* but some non-Posix systems misbehave unless the slashes are omitted. -*/ -{ -# ifndef SLASHSLASH_is_SLASH -# define SLASHSLASH_is_SLASH 0 -# endif - size_t dlen = strlen(d); - if (!SLASHSLASH_is_SLASH && dlen==2 && isSLASH(d[0]) && isSLASH(d[1])) - --dlen; - else - while (dlen && isSLASH(d[dlen-1])) - --dlen; - return dlen; -} - -#ifndef isSLASH - int -isSLASH(c) - int c; -{ - switch (c) { - case SLASHes: - return true; - default: - return false; - } -} -#endif - - -#if !has_getcwd && !has_getwd - - char * -getcwd(path, size) - char *path; - size_t size; -{ - static char const usrbinpwd[] = "/usr/bin/pwd"; -# define binpwd (usrbinpwd+4) - - register FILE *fp; - register int c; - register char *p, *lim; - int closeerrno, closeerror, e, fd[2], readerror, toolong, wstatus; - pid_t child; - - if (!size) { - errno = EINVAL; - return 0; - } - if (pipe(fd) != 0) - return 0; -# if bad_wait_if_SIGCHLD_ignored -# ifndef SIGCHLD -# define SIGCHLD SIGCLD -# endif - VOID signal(SIGCHLD, SIG_DFL); -# endif - if (!(child = vfork())) { - if ( - close(fd[0]) == 0 && - (fd[1] == STDOUT_FILENO || -# ifdef F_DUPFD - (VOID close(STDOUT_FILENO), - fcntl(fd[1], F_DUPFD, STDOUT_FILENO)) -# else - dup2(fd[1], STDOUT_FILENO) -# endif - == STDOUT_FILENO && - close(fd[1]) == 0 - ) - ) { - VOID close(STDERR_FILENO); - VOID execl(binpwd, binpwd, (char *)0); - VOID execl(usrbinpwd, usrbinpwd, (char *)0); - } - _exit(EXIT_FAILURE); - } - e = errno; - closeerror = close(fd[1]); - closeerrno = errno; - fp = 0; - readerror = toolong = wstatus = 0; - p = path; - if (0 <= child) { - fp = fdopen(fd[0], "r"); - e = errno; - if (fp) { - lim = p + size; - for (p = path; ; *p++ = c) { - if ((c=getc(fp)) < 0) { - if (feof(fp)) - break; - if (ferror(fp)) { - readerror = 1; - e = errno; - break; - } - } - if (p == lim) { - toolong = 1; - break; - } - } - } -# if has_waitpid - if (waitpid(child, &wstatus, 0) < 0) - wstatus = 1; -# else - { - pid_t w; - do { - if ((w = wait(&wstatus)) < 0) { - wstatus = 1; - break; - } - } while (w != child); - } -# endif - } - if (!fp) { - VOID close(fd[0]); - errno = e; - return 0; - } - if (fclose(fp) != 0) - return 0; - if (readerror) { - errno = e; - return 0; - } - if (closeerror) { - errno = closeerrno; - return 0; - } - if (toolong) { - errno = ERANGE; - return 0; - } - if (wstatus || p == path || *--p != '\n') { - errno = EACCES; - return 0; - } - *p = '\0'; - return path; -} -#endif - - -#ifdef PAIRTEST -/* test program for pairnames() and getfullRCSname() */ - -char const cmdid[] = "pair"; - -main(argc, argv) -int argc; char *argv[]; -{ - int result; - int initflag; - quietflag = initflag = false; - - while(--argc, ++argv, argc>=1 && ((*argv)[0] == '-')) { - switch ((*argv)[1]) { - - case 'p': workstdout = stdout; - break; - case 'i': initflag=true; - break; - case 'q': quietflag=true; - break; - default: error("unknown option: %s", *argv); - break; - } - } - - do { - RCSname = workname = 0; - result = pairnames(argc,argv,rcsreadopen,!initflag,quietflag); - if (result!=0) { - diagnose("RCS pathname: %s; working pathname: %s\nFull RCS pathname: %s\n", - RCSname, workname, getfullRCSname() - ); - } - switch (result) { - case 0: continue; /* already paired file */ - - case 1: if (initflag) { - rcserror("already exists"); - } else { - diagnose("RCS file %s exists\n", RCSname); - } - Ifclose(finptr); - break; - - case -1:diagnose("RCS file doesn't exist\n"); - break; - } - - } while (++argv, --argc>=1); - -} - - void -exiterr() -{ - dirtempunlink(); - tempunlink(); - _exit(EXIT_FAILURE); -} -#endif diff --git a/gnu/usr.bin/rcs/lib/rcsgen.c b/gnu/usr.bin/rcs/lib/rcsgen.c deleted file mode 100644 index 35d8702..0000000 --- a/gnu/usr.bin/rcs/lib/rcsgen.c +++ /dev/null @@ -1,681 +0,0 @@ -/* Generate RCS revisions. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.16 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.15 1995/06/01 16:23:43 eggert - * (putadmin): Open RCS file with FOPEN_WB. - * - * Revision 5.14 1994/03/17 14:05:48 eggert - * Work around SVR4 stdio performance bug. - * Flush stderr after prompt. Remove lint. - * - * Revision 5.13 1993/11/03 17:42:27 eggert - * Don't discard ignored phrases. Improve quality of diagnostics. - * - * Revision 5.12 1992/07/28 16:12:44 eggert - * Statement macro names now end in _. - * Be consistent about pathnames vs filenames. - * - * Revision 5.11 1992/01/24 18:44:19 eggert - * Move put routines here from rcssyn.c. - * Add support for bad_creat0. - * - * Revision 5.10 1991/10/07 17:32:46 eggert - * Fix log bugs, e.g. ci -t/dev/null when has_mmap. - * - * Revision 5.9 1991/09/10 22:15:46 eggert - * Fix test for redirected stdin. - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Add piece tables. Tune. - * - * Revision 5.7 1991/04/21 11:58:24 eggert - * Add MS-DOS support. - * - * Revision 5.6 1990/12/27 19:54:26 eggert - * Fix bug: rcs -t inserted \n, making RCS file grow. - * - * Revision 5.5 1990/12/04 05:18:45 eggert - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.4 1990/11/01 05:03:47 eggert - * Add -I and new -t behavior. Permit arbitrary data in logs. - * - * Revision 5.3 1990/09/21 06:12:43 hammer - * made putdesc() treat stdin the same whether or not it was from a terminal - * by making it recognize that a single '.' was then end of the - * description always - * - * Revision 5.2 1990/09/04 08:02:25 eggert - * Fix `co -p1.1 -ko' bug. Standardize yes-or-no procedure. - * - * Revision 5.1 1990/08/29 07:14:01 eggert - * Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:12:52 eggert - * Remove compile-time limits; use malloc instead. - * Ansify and Posixate. - * - * Revision 4.7 89/05/01 15:12:49 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.6 88/08/28 14:59:10 eggert - * Shrink stdio code size; allow cc -R; remove lint; isatty() -> ttystdin() - * - * Revision 4.5 87/12/18 11:43:25 narten - * additional lint cleanups, and a bug fix from the 4.3BSD version that - * keeps "ci" from sticking a '\377' into the description if you run it - * with a zero-length file as the description. (Guy Harris) - * - * Revision 4.4 87/10/18 10:35:10 narten - * Updating version numbers. Changes relative to 1.1 actually relative to - * 4.2 - * - * Revision 1.3 87/09/24 13:59:51 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:27 jenkins - * Port to suns - * - * Revision 4.2 83/12/02 23:01:39 wft - * merged 4.1 and 3.3.1.1 (clearerr(stdin)). - * - * Revision 4.1 83/05/10 16:03:33 wft - * Changed putamin() to abort if trying to reread redirected stdin. - * Fixed getdesc() to output a prompt on initial newline. - * - * Revision 3.3.1.1 83/10/19 04:21:51 lepreau - * Added clearerr(stdin) for re-reading description from stdin. - * - * Revision 3.3 82/11/28 21:36:49 wft - * 4.2 prerelease - * - * Revision 3.3 82/11/28 21:36:49 wft - * Replaced ferror() followed by fclose() with ffclose(). - * Putdesc() now suppresses the prompts if stdin - * is not a terminal. A pointer to the current log message is now - * inserted into the corresponding delta, rather than leaving it in a - * global variable. - * - * Revision 3.2 82/10/18 21:11:26 wft - * I added checks for write errors during editing, and improved - * the prompt on putdesc(). - * - * Revision 3.1 82/10/13 15:55:09 wft - * corrected type of variables assigned to by getc (char --> int) - */ - - - - -#include "rcsbase.h" - -libId(genId, "$FreeBSD$") - -int interactiveflag; /* Should we act as if stdin is a tty? */ -struct buf curlogbuf; /* buffer for current log message */ - -enum stringwork { enter, copy, edit, expand, edit_expand }; - -static void putdelta P((struct hshentry const*,FILE*)); -static void scandeltatext P((struct hshentry*,enum stringwork,int)); - - - - - char const * -buildrevision(deltas, target, outfile, expandflag) - struct hshentries const *deltas; - struct hshentry *target; - FILE *outfile; - int expandflag; -/* Function: Generates the revision given by target - * by retrieving all deltas given by parameter deltas and combining them. - * If outfile is set, the revision is output to it, - * otherwise written into a temporary file. - * Temporary files are allocated by maketemp(). - * if expandflag is set, keyword expansion is performed. - * Return 0 if outfile is set, the name of the temporary file otherwise. - * - * Algorithm: Copy initial revision unchanged. Then edit all revisions but - * the last one into it, alternating input and output files (resultname and - * editname). The last revision is then edited in, performing simultaneous - * keyword substitution (this saves one extra pass). - * All this simplifies if only one revision needs to be generated, - * or no keyword expansion is necessary, or if output goes to stdout. - */ -{ - if (deltas->first == target) { - /* only latest revision to generate */ - openfcopy(outfile); - scandeltatext(target, expandflag?expand:copy, true); - if (outfile) - return 0; - else { - Ozclose(&fcopy); - return resultname; - } - } else { - /* several revisions to generate */ - /* Get initial revision without keyword expansion. */ - scandeltatext(deltas->first, enter, false); - while ((deltas=deltas->rest)->rest) { - /* do all deltas except last one */ - scandeltatext(deltas->first, edit, false); - } - if (expandflag || outfile) { - /* first, get to beginning of file*/ - finishedit((struct hshentry*)0, outfile, false); - } - scandeltatext(target, expandflag?edit_expand:edit, true); - finishedit( - expandflag ? target : (struct hshentry*)0, - outfile, true - ); - if (outfile) - return 0; - Ozclose(&fcopy); - return resultname; - } -} - - - - static void -scandeltatext(delta, func, needlog) - struct hshentry *delta; - enum stringwork func; - int needlog; -/* Function: Scans delta text nodes up to and including the one given - * by delta. For the one given by delta, the log message is saved into - * delta->log if needlog is set; func specifies how to handle the text. - * Similarly, if needlog, delta->igtext is set to the ignored phrases. - * Assumes the initial lexeme must be read in first. - * Does not advance nexttok after it is finished. - */ -{ - struct hshentry const *nextdelta; - struct cbuf cb; - - for (;;) { - if (eoflex()) - fatserror("can't find delta for revision %s", delta->num); - nextlex(); - if (!(nextdelta=getnum())) { - fatserror("delta number corrupted"); - } - getkeystring(Klog); - if (needlog && delta==nextdelta) { - cb = savestring(&curlogbuf); - delta->log = cleanlogmsg(curlogbuf.string, cb.size); - nextlex(); - delta->igtext = getphrases(Ktext); - } else {readstring(); - ignorephrases(Ktext); - } - getkeystring(Ktext); - - if (delta==nextdelta) - break; - readstring(); /* skip over it */ - - } - switch (func) { - case enter: enterstring(); break; - case copy: copystring(); break; - case expand: xpandstring(delta); break; - case edit: editstring((struct hshentry *)0); break; - case edit_expand: editstring(delta); break; - } -} - - struct cbuf -cleanlogmsg(m, s) - char *m; - size_t s; -{ - register char *t = m; - register char const *f = t; - struct cbuf r; - while (s) { - --s; - if ((*t++ = *f++) == '\n') - while (m < --t) - if (t[-1]!=' ' && t[-1]!='\t') { - *t++ = '\n'; - break; - } - } - while (m < t && (t[-1]==' ' || t[-1]=='\t' || t[-1]=='\n')) - --t; - r.string = m; - r.size = t - m; - return r; -} - - -int ttystdin() -{ - static int initialized; - if (!initialized) { - if (!interactiveflag) - interactiveflag = isatty(STDIN_FILENO); - initialized = true; - } - return interactiveflag; -} - - int -getcstdin() -{ - register FILE *in; - register int c; - - in = stdin; - if (feof(in) && ttystdin()) - clearerr(in); - c = getc(in); - if (c == EOF) { - testIerror(in); - if (feof(in) && ttystdin()) - afputc('\n',stderr); - } - return c; -} - -#if has_prototypes - int -yesorno(int default_answer, char const *question, ...) -#else - /*VARARGS2*/ int - yesorno(default_answer, question, va_alist) - int default_answer; char const *question; va_dcl -#endif -{ - va_list args; - register int c, r; - if (!quietflag && ttystdin()) { - oflush(); - vararg_start(args, question); - fvfprintf(stderr, question, args); - va_end(args); - eflush(); - r = c = getcstdin(); - while (c!='\n' && !feof(stdin)) - c = getcstdin(); - if (r=='y' || r=='Y') - return true; - if (r=='n' || r=='N') - return false; - } - return default_answer; -} - - - void -putdesc(textflag, textfile) - int textflag; - char *textfile; -/* Function: puts the descriptive text into file frewrite. - * if finptr && !textflag, the text is copied from the old description. - * Otherwise, if textfile, the text is read from that - * file, or from stdin, if !textfile. - * A textfile with a leading '-' is treated as a string, not a pathname. - * If finptr, the old descriptive text is discarded. - * Always clears foutptr. - */ -{ - static struct buf desc; - static struct cbuf desclean; - - register FILE *txt; - register int c; - register FILE * frew; - register char *p; - register size_t s; - char const *plim; - - frew = frewrite; - if (finptr && !textflag) { - /* copy old description */ - aprintf(frew, "\n\n%s%c", Kdesc, nextc); - foutptr = frewrite; - getdesc(false); - foutptr = 0; - } else { - foutptr = 0; - /* get new description */ - if (finptr) { - /*skip old description*/ - getdesc(false); - } - aprintf(frew,"\n\n%s\n%c",Kdesc,SDELIM); - if (!textfile) - desclean = getsstdin( - "t-", "description", - "NOTE: This is NOT the log message!\n", &desc - ); - else if (!desclean.string) { - if (*textfile == '-') { - p = textfile + 1; - s = strlen(p); - } else { - if (!(txt = fopenSafer(textfile, "r"))) - efaterror(textfile); - bufalloc(&desc, 1); - p = desc.string; - plim = p + desc.size; - for (;;) { - if ((c=getc(txt)) == EOF) { - testIerror(txt); - if (feof(txt)) - break; - } - if (plim <= p) - p = bufenlarge(&desc, &plim); - *p++ = c; - } - if (fclose(txt) != 0) - Ierror(); - s = p - desc.string; - p = desc.string; - } - desclean = cleanlogmsg(p, s); - } - putstring(frew, false, desclean, true); - aputc_('\n', frew) - } -} - - struct cbuf -getsstdin(option, name, note, buf) - char const *option, *name, *note; - struct buf *buf; -{ - register int c; - register char *p; - register size_t i; - register int tty = ttystdin(); - - if (tty) { - aprintf(stderr, - "enter %s, terminated with single '.' or end of file:\n%s>> ", - name, note - ); - eflush(); - } else if (feof(stdin)) - rcsfaterror("can't reread redirected stdin for %s; use -%s<%s>", - name, option, name - ); - - for ( - i = 0, p = 0; - c = getcstdin(), !feof(stdin); - bufrealloc(buf, i+1), p = buf->string, p[i++] = c - ) - if (c == '\n') - if (i && p[i-1]=='.' && (i==1 || p[i-2]=='\n')) { - /* Remove trailing '.'. */ - --i; - break; - } else if (tty) { - aputs(">> ", stderr); - eflush(); - } - return cleanlogmsg(p, i); -} - - - void -putadmin() -/* Output the admin node. */ -{ - register FILE *fout; - struct assoc const *curassoc; - struct rcslock const *curlock; - struct access const *curaccess; - - if (!(fout = frewrite)) { -# if bad_creat0 - ORCSclose(); - fout = fopenSafer(makedirtemp(0), FOPEN_WB); -# else - int fo = fdlock; - fdlock = -1; - fout = fdopen(fo, FOPEN_WB); -# endif - - if (!(frewrite = fout)) - efaterror(RCSname); - } - - /* - * Output the first character with putc, not printf. - * Otherwise, an SVR4 stdio bug buffers output inefficiently. - */ - aputc_(*Khead, fout) - aprintf(fout, "%s\t%s;\n", Khead + 1, Head?Head->num:""); - if (Dbranch && VERSION(4)<=RCSversion) - aprintf(fout, "%s\t%s;\n", Kbranch, Dbranch); - - aputs(Kaccess, fout); - curaccess = AccessList; - while (curaccess) { - aprintf(fout, "\n\t%s", curaccess->login); - curaccess = curaccess->nextaccess; - } - aprintf(fout, ";\n%s", Ksymbols); - curassoc = Symbols; - while (curassoc) { - aprintf(fout, "\n\t%s:%s", curassoc->symbol, curassoc->num); - curassoc = curassoc->nextassoc; - } - aprintf(fout, ";\n%s", Klocks); - curlock = Locks; - while (curlock) { - aprintf(fout, "\n\t%s:%s", curlock->login, curlock->delta->num); - curlock = curlock->nextlock; - } - if (StrictLocks) aprintf(fout, "; %s", Kstrict); - aprintf(fout, ";\n"); - if (Comment.size) { - aprintf(fout, "%s\t", Kcomment); - putstring(fout, true, Comment, false); - aprintf(fout, ";\n"); - } - if (Expand != KEYVAL_EXPAND) - aprintf(fout, "%s\t%c%s%c;\n", - Kexpand, SDELIM, expand_names[Expand], SDELIM - ); - awrite(Ignored.string, Ignored.size, fout); - aputc_('\n', fout) -} - - - static void -putdelta(node, fout) - register struct hshentry const *node; - register FILE * fout; -/* Output the delta NODE to FOUT. */ -{ - struct branchhead const *nextbranch; - - if (!node) return; - - aprintf(fout, "\n%s\n%s\t%s;\t%s %s;\t%s %s;\nbranches", - node->num, - Kdate, node->date, - Kauthor, node->author, - Kstate, node->state?node->state:"" - ); - nextbranch = node->branches; - while (nextbranch) { - aprintf(fout, "\n\t%s", nextbranch->hsh->num); - nextbranch = nextbranch->nextbranch; - } - - aprintf(fout, ";\n%s\t%s;\n", Knext, node->next?node->next->num:""); - awrite(node->ig.string, node->ig.size, fout); -} - - - void -puttree(root, fout) - struct hshentry const *root; - register FILE *fout; -/* Output the delta tree with base ROOT in preorder to FOUT. */ -{ - struct branchhead const *nextbranch; - - if (!root) return; - - if (root->selector) - putdelta(root, fout); - - puttree(root->next, fout); - - nextbranch = root->branches; - while (nextbranch) { - puttree(nextbranch->hsh, fout); - nextbranch = nextbranch->nextbranch; - } -} - - - int -putdtext(delta, srcname, fout, diffmt) - struct hshentry const *delta; - char const *srcname; - FILE *fout; - int diffmt; -/* - * Output a deltatext node with delta number DELTA->num, log message DELTA->log, - * ignored phrases DELTA->igtext and text SRCNAME to FOUT. - * Double up all SDELIMs in both the log and the text. - * Make sure the log message ends in \n. - * Return false on error. - * If DIFFMT, also check that the text is valid diff -n output. - */ -{ - RILE *fin; - if (!(fin = Iopen(srcname, "r", (struct stat*)0))) { - eerror(srcname); - return false; - } - putdftext(delta, fin, fout, diffmt); - Ifclose(fin); - return true; -} - - void -putstring(out, delim, s, log) - register FILE *out; - struct cbuf s; - int delim, log; -/* - * Output to OUT one SDELIM if DELIM, then the string S with SDELIMs doubled. - * If LOG is set then S is a log string; append a newline if S is nonempty. - */ -{ - register char const *sp; - register size_t ss; - - if (delim) - aputc_(SDELIM, out) - sp = s.string; - for (ss = s.size; ss; --ss) { - if (*sp == SDELIM) - aputc_(SDELIM, out) - aputc_(*sp++, out) - } - if (s.size && log) - aputc_('\n', out) - aputc_(SDELIM, out) -} - - void -putdftext(delta, finfile, foutfile, diffmt) - struct hshentry const *delta; - RILE *finfile; - FILE *foutfile; - int diffmt; -/* like putdtext(), except the source file is already open */ -{ - declarecache; - register FILE *fout; - register int c; - register RILE *fin; - int ed; - struct diffcmd dc; - - fout = foutfile; - aprintf(fout, DELNUMFORM, delta->num, Klog); - - /* put log */ - putstring(fout, true, delta->log, true); - aputc_('\n', fout) - - /* put ignored phrases */ - awrite(delta->igtext.string, delta->igtext.size, fout); - - /* put text */ - aprintf(fout, "%s\n%c", Ktext, SDELIM); - - fin = finfile; - setupcache(fin); - if (!diffmt) { - /* Copy the file */ - cache(fin); - for (;;) { - cachegeteof_(c, break;) - if (c==SDELIM) aputc_(SDELIM, fout) /*double up SDELIM*/ - aputc_(c, fout) - } - } else { - initdiffcmd(&dc); - while (0 <= (ed = getdiffcmd(fin, false, fout, &dc))) - if (ed) { - cache(fin); - while (dc.nlines--) - do { - cachegeteof_(c, { if (!dc.nlines) goto OK_EOF; unexpected_EOF(); }) - if (c == SDELIM) - aputc_(SDELIM, fout) - aputc_(c, fout) - } while (c != '\n'); - uncache(fin); - } - } - OK_EOF: - aprintf(fout, "%c\n", SDELIM); -} diff --git a/gnu/usr.bin/rcs/lib/rcskeep.c b/gnu/usr.bin/rcs/lib/rcskeep.c deleted file mode 100644 index 4a90f85..0000000 --- a/gnu/usr.bin/rcs/lib/rcskeep.c +++ /dev/null @@ -1,452 +0,0 @@ -/* Extract RCS keyword string values from working files. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.10 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.9 1995/06/01 16:23:43 eggert - * (getoldkeys): Don't panic if a Name: is empty. - * - * Revision 5.8 1994/03/17 14:05:48 eggert - * Remove lint. - * - * Revision 5.7 1993/11/09 17:40:15 eggert - * Use simpler timezone parsing strategy now that we're using ISO 8601 format. - * - * Revision 5.6 1993/11/03 17:42:27 eggert - * Scan for Name keyword. Improve quality of diagnostics. - * - * Revision 5.5 1992/07/28 16:12:44 eggert - * Statement macro names now end in _. - * - * Revision 5.4 1991/08/19 03:13:55 eggert - * Tune. - * - * Revision 5.3 1991/04/21 11:58:25 eggert - * Shorten names to keep them distinct on shortname hosts. - * - * Revision 5.2 1990/10/04 06:30:20 eggert - * Parse time zone offsets; future RCS versions may output them. - * - * Revision 5.1 1990/09/20 02:38:56 eggert - * ci -k now checks dates more thoroughly. - * - * Revision 5.0 1990/08/22 08:12:53 eggert - * Retrieve old log message if there is one. - * Don't require final newline. - * Remove compile-time limits; use malloc instead. Tune. - * Permit dates past 1999/12/31. Ansify and Posixate. - * - * Revision 4.6 89/05/01 15:12:56 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.5 88/08/09 19:13:03 eggert - * Remove lint and speed up by making FILE *fp local, not global. - * - * Revision 4.4 87/12/18 11:44:21 narten - * more lint cleanups (Guy Harris) - * - * Revision 4.3 87/10/18 10:35:50 narten - * Updating version numbers. Changes relative to 1.1 actually relative - * to 4.1 - * - * Revision 1.3 87/09/24 14:00:00 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:29 jenkins - * Port to suns - * - * Revision 4.1 83/05/10 16:26:44 wft - * Added new markers Id and RCSfile; extraction added. - * Marker matching with trymatch(). - * - * Revision 3.2 82/12/24 12:08:26 wft - * added missing #endif. - * - * Revision 3.1 82/12/04 13:22:41 wft - * Initial revision. - * - */ - -#include "rcsbase.h" - -libId(keepId, "$FreeBSD$") - -static int badly_terminated P((void)); -static int checknum P((char const*)); -static int get0val P((int,RILE*,struct buf*,int)); -static int getval P((RILE*,struct buf*,int)); -static int keepdate P((RILE*)); -static int keepid P((int,RILE*,struct buf*)); -static int keeprev P((RILE*)); - -int prevkeys; -struct buf prevauthor, prevdate, prevname, prevrev, prevstate; - - int -getoldkeys(fp) - register RILE *fp; -/* Function: Tries to read keyword values for author, date, - * revision number, and state out of the file fp. - * If fp is null, workname is opened and closed instead of using fp. - * The results are placed into - * prevauthor, prevdate, prevname, prevrev, prevstate. - * Aborts immediately if it finds an error and returns false. - * If it returns true, it doesn't mean that any of the - * values were found; instead, check to see whether the corresponding arrays - * contain the empty string. - */ -{ - register int c; - char keyword[keylength+1]; - register char * tp; - int needs_closing; - int prevname_found; - - if (prevkeys) - return true; - - needs_closing = false; - if (!fp) { - if (!(fp = Iopen(workname, FOPEN_R_WORK, (struct stat*)0))) { - eerror(workname); - return false; - } - needs_closing = true; - } - - /* initialize to empty */ - bufscpy(&prevauthor, ""); - bufscpy(&prevdate, ""); - bufscpy(&prevname, ""); prevname_found = 0; - bufscpy(&prevrev, ""); - bufscpy(&prevstate, ""); - - c = '\0'; /* anything but KDELIM */ - for (;;) { - if ( c==KDELIM) { - do { - /* try to get keyword */ - tp = keyword; - for (;;) { - Igeteof_(fp, c, goto ok;) - switch (c) { - default: - if (keyword+keylength <= tp) - break; - *tp++ = c; - continue; - - case '\n': case KDELIM: case VDELIM: - break; - } - break; - } - } while (c==KDELIM); - if (c!=VDELIM) continue; - *tp = c; - Igeteof_(fp, c, break;) - switch (c) { - case ' ': case '\t': break; - default: continue; - } - - switch (trymatch(keyword)) { - case Author: - if (!keepid(0, fp, &prevauthor)) - return false; - c = 0; - break; - case Date: - if (!(c = keepdate(fp))) - return false; - break; - case Header: - case Id: - case LocalId: - if (!( - getval(fp, (struct buf*)0, false) && - keeprev(fp) && - (c = keepdate(fp)) && - keepid(c, fp, &prevauthor) && - keepid(0, fp, &prevstate) - )) - return false; - /* Skip either ``who'' (new form) or ``Locker: who'' (old). */ - if (getval(fp, (struct buf*)0, true) && - getval(fp, (struct buf*)0, true)) - c = 0; - else if (nerror) - return false; - else - c = KDELIM; - break; - case Locker: - (void) getval(fp, (struct buf*)0, false); - c = 0; - break; - case Log: - case RCSfile: - case Source: - if (!getval(fp, (struct buf*)0, false)) - return false; - c = 0; - break; - case Name: - if (getval(fp, &prevname, false)) { - if (*prevname.string) - checkssym(prevname.string); - prevname_found = 1; - } - c = 0; - break; - case Revision: - if (!keeprev(fp)) - return false; - c = 0; - break; - case State: - if (!keepid(0, fp, &prevstate)) - return false; - c = 0; - break; - default: - continue; - } - if (!c) - Igeteof_(fp, c, c=0;) - if (c != KDELIM) { - workerror("closing %c missing on keyword", KDELIM); - return false; - } - if (prevname_found && - *prevauthor.string && *prevdate.string && - *prevrev.string && *prevstate.string - ) - break; - } - Igeteof_(fp, c, break;) - } - - ok: - if (needs_closing) - Ifclose(fp); - else - Irewind(fp); - prevkeys = true; - return true; -} - - static int -badly_terminated() -{ - workerror("badly terminated keyword value"); - return false; -} - - static int -getval(fp, target, optional) - register RILE *fp; - struct buf *target; - int optional; -/* Reads a keyword value from FP into TARGET. - * Returns true if one is found, false otherwise. - * Does not modify target if it is 0. - * Do not report an error if OPTIONAL is set and KDELIM is found instead. - */ -{ - int c; - Igeteof_(fp, c, return badly_terminated();) - return get0val(c, fp, target, optional); -} - - static int -get0val(c, fp, target, optional) - register int c; - register RILE *fp; - struct buf *target; - int optional; -/* Reads a keyword value from C+FP into TARGET, perhaps OPTIONALly. - * Same as getval, except C is the lookahead character. - */ -{ register char * tp; - char const *tlim; - register int got1; - - if (target) { - bufalloc(target, 1); - tp = target->string; - tlim = tp + target->size; - } else - tlim = tp = 0; - got1 = false; - for (;;) { - switch (c) { - default: - got1 = true; - if (tp) { - *tp++ = c; - if (tlim <= tp) - tp = bufenlarge(target, &tlim); - } - break; - - case ' ': - case '\t': - if (tp) { - *tp = 0; -# ifdef KEEPTEST - VOID printf("getval: %s\n", target); -# endif - } - return got1; - - case KDELIM: - if (!got1 && optional) - return false; - /* fall into */ - case '\n': - case 0: - return badly_terminated(); - } - Igeteof_(fp, c, return badly_terminated();) - } -} - - - static int -keepdate(fp) - RILE *fp; -/* Function: reads a date prevdate; checks format - * Return 0 on error, lookahead character otherwise. - */ -{ - struct buf prevday, prevtime; - register int c; - - c = 0; - bufautobegin(&prevday); - if (getval(fp,&prevday,false)) { - bufautobegin(&prevtime); - if (getval(fp,&prevtime,false)) { - Igeteof_(fp, c, c=0;) - if (c) { - register char const *d = prevday.string, *t = prevtime.string; - bufalloc(&prevdate, strlen(d) + strlen(t) + 9); - VOID sprintf(prevdate.string, "%s%s %s%s", - /* Parse dates put out by old versions of RCS. */ - isdigit(d[0]) && isdigit(d[1]) && !isdigit(d[2]) - ? "19" : "", - d, t, - strchr(t,'-') || strchr(t,'+') ? "" : "+0000" - ); - } - } - bufautoend(&prevtime); - } - bufautoend(&prevday); - return c; -} - - static int -keepid(c, fp, b) - int c; - RILE *fp; - struct buf *b; -/* Get previous identifier from C+FP into B. */ -{ - if (!c) - Igeteof_(fp, c, return false;) - if (!get0val(c, fp, b, false)) - return false; - checksid(b->string); - return !nerror; -} - - static int -keeprev(fp) - RILE *fp; -/* Get previous revision from FP into prevrev. */ -{ - return getval(fp,&prevrev,false) && checknum(prevrev.string); -} - - - static int -checknum(s) - char const *s; -{ - register char const *sp; - register int dotcount = 0; - for (sp=s; ; sp++) { - switch (*sp) { - case 0: - if (dotcount & 1) - return true; - else - break; - - case '.': - dotcount++; - continue; - - default: - if (isdigit(*sp)) - continue; - break; - } - break; - } - workerror("%s is not a revision number", s); - return false; -} - - - -#ifdef KEEPTEST - -/* Print the keyword values found. */ - -char const cmdid[] ="keeptest"; - - int -main(argc, argv) -int argc; char *argv[]; -{ - while (*(++argv)) { - workname = *argv; - getoldkeys((RILE*)0); - VOID printf("%s: revision: %s, date: %s, author: %s, name: %s, state: %s\n", - *argv, prevrev.string, prevdate.string, prevauthor.string, prevname.string, prevstate.string); - } - exitmain(EXIT_SUCCESS); -} -#endif diff --git a/gnu/usr.bin/rcs/lib/rcskeys.c b/gnu/usr.bin/rcs/lib/rcskeys.c deleted file mode 100644 index 378f57d..0000000 --- a/gnu/usr.bin/rcs/lib/rcskeys.c +++ /dev/null @@ -1,186 +0,0 @@ -/* RCS keyword table and match operation */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.4 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.3 1993/11/03 17:42:27 eggert - * Add Name keyword. - * - * Revision 5.2 1991/08/19 03:13:55 eggert - * Say `T const' instead of `const T'; it's less confusing for pointer types. - * (This change was made in other source files too.) - * - * Revision 5.1 1991/04/21 11:58:25 eggert - * Don't put , just before } in initializer. - * - * Revision 5.0 1990/08/22 08:12:54 eggert - * Add -k. Ansify and Posixate. - * - * Revision 4.3 89/05/01 15:13:02 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.2 87/10/18 10:36:33 narten - * Updating version numbers. Changes relative to 1.1 actuallyt - * relative to 4.1 - * - * Revision 1.2 87/09/24 14:00:10 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 4.1 83/05/04 10:06:53 wft - * Initial revision. - * - */ - - -#include "rcsbase.h" - -libId(keysId, "$FreeBSD$") - - -char const *Keyword[] = { - /* This must be in the same order as rcsbase.h's enum markers type. */ - 0, - AUTHOR, DATE, HEADER, IDH, - LOCKER, LOG, NAME, RCSFILE, REVISION, SOURCE, STATE, CVSHEADER, - NULL -}; - -/* Expand all keywords by default */ -static int ExpandKeyword[] = { - false, - true, true, true, true, - true, true, true, true, true, true, true, true, - true -}; -enum markers LocalIdMode = Id; - - enum markers -trymatch(string) - char const *string; -/* function: Checks whether string starts with a keyword followed - * by a KDELIM or a VDELIM. - * If successful, returns the appropriate marker, otherwise Nomatch. - */ -{ - register int j; - register char const *p, *s; - for (j = sizeof(Keyword)/sizeof(*Keyword); (--j); ) { - if (!ExpandKeyword[j]) - continue; - /* try next keyword */ - p = Keyword[j]; - if (p == NULL) - continue; - s = string; - while (*p++ == *s++) { - if (!*p) - switch (*s) { - case KDELIM: - case VDELIM: - return (enum markers)j; - default: - return Nomatch; - } - } - } - return(Nomatch); -} - - void -setIncExc(arg) - char const *arg; -/* Sets up the ExpandKeyword table according to command-line flags */ -{ - char *key; - char *copy, *next; - int include = 0, j; - - copy = strdup(arg); - next = copy; - switch (*next++) { - case 'e': - include = false; - break; - case 'i': - include = true; - break; - default: - free(copy); - return; - } - if (include) - for (j = sizeof(Keyword)/sizeof(*Keyword); (--j); ) - ExpandKeyword[j] = false; - key = strtok(next, ","); - while (key) { - for (j = sizeof(Keyword)/sizeof(*Keyword); (--j); ) { - if (Keyword[j] == NULL) - continue; - if (!strcmp(key, Keyword[j])) - ExpandKeyword[j] = include; - } - key = strtok(NULL, ","); - } - free(copy); - return; -} - - void -setRCSLocalId(string) - char const *string; -/* function: sets local RCS id and RCSLOCALID envariable */ -{ - static char local_id[keylength+1]; - char *copy, *next, *key; - int j; - - copy = strdup(string); - next = copy; - key = strtok(next, "="); - if (strlen(key) > keylength) - faterror("LocalId is too long"); - VOID strcpy(local_id, key); - Keyword[LocalId] = local_id; - - /* options? */ - while (key = strtok(NULL, ",")) { - if (!strcmp(key, Keyword[Id])) - LocalIdMode=Id; - else if (!strcmp(key, Keyword[Header])) - LocalIdMode=Header; - else if (!strcmp(key, Keyword[CVSHeader])) - LocalIdMode=CVSHeader; - else - error("Unknown LocalId mode"); - } - free(copy); -} diff --git a/gnu/usr.bin/rcs/lib/rcslex.c b/gnu/usr.bin/rcs/lib/rcslex.c deleted file mode 100644 index 7a11f79..0000000 --- a/gnu/usr.bin/rcs/lib/rcslex.c +++ /dev/null @@ -1,1568 +0,0 @@ -/* lexical analysis of RCS files */ - -/****************************************************************************** - * Lexical Analysis. - * hashtable, Lexinit, nextlex, getlex, getkey, - * getid, getnum, readstring, printstring, savestring, - * checkid, fatserror, error, faterror, warn, diagnose - * Testprogram: define LEXDB - ****************************************************************************** - */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - - - -/* - * Revision 5.19 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.18 1995/06/01 16:23:43 eggert - * (map_fd_deallocate,mmap_deallocate,read_deallocate,nothing_to_deallocate): - * New functions. - * (Iclose): If large_memory and maps_memory, use them to deallocate mapping. - * (fd2RILE): Use map_fd if available. - * If one mapping method fails, try the next instead of giving up; - * if they all fail, fall back on ordinary read. - * Work around bug: root mmap over NFS succeeds, but accessing dumps core. - * Use MAP_FAILED macro for mmap failure, and `char *' instead of caddr_t. - * (advise_access): Use madvise only if this instance used mmap. - * (Iopen): Use fdSafer to get safer file descriptor. - * (aflush): Moved here from rcsedit.c. - * - * Revision 5.17 1994/03/20 04:52:58 eggert - * Don't worry if madvise fails. Add Orewind. Remove lint. - * - * Revision 5.16 1993/11/09 17:55:29 eggert - * Fix `label: }' typo. - * - * Revision 5.15 1993/11/03 17:42:27 eggert - * Improve quality of diagnostics by putting file names in them more often. - * Don't discard ignored phrases. - * - * Revision 5.14 1992/07/28 16:12:44 eggert - * Identifiers may now start with a digit and (unless they are symbolic names) - * may contain `.'. Avoid `unsigned'. Statement macro names now end in _. - * - * Revision 5.13 1992/02/17 23:02:27 eggert - * Work around NFS mmap SIGBUS problem. - * - * Revision 5.12 1992/01/06 02:42:34 eggert - * Use OPEN_O_BINARY if mode contains 'b'. - * - * Revision 5.11 1991/11/03 03:30:44 eggert - * Fix porting bug to ancient hosts lacking vfprintf. - * - * Revision 5.10 1991/10/07 17:32:46 eggert - * Support piece tables even if !has_mmap. - * - * Revision 5.9 1991/09/24 00:28:42 eggert - * Don't export errsay(). - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Add eoflex(), mmap support. Tune. - * - * Revision 5.7 1991/04/21 11:58:26 eggert - * Add MS-DOS support. - * - * Revision 5.6 1991/02/25 07:12:42 eggert - * Work around fputs bug. strsave -> str_save (DG/UX name clash) - * - * Revision 5.5 1990/12/04 05:18:47 eggert - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.4 1990/11/19 20:05:28 hammer - * no longer gives warning about unknown keywords if -q is specified - * - * Revision 5.3 1990/11/01 05:03:48 eggert - * When ignoring unknown phrases, copy them to the output RCS file. - * - * Revision 5.2 1990/09/04 08:02:27 eggert - * Count RCS lines better. - * - * Revision 5.1 1990/08/29 07:14:03 eggert - * Work around buggy compilers with defective argument promotion. - * - * Revision 5.0 1990/08/22 08:12:55 eggert - * Remove compile-time limits; use malloc instead. - * Report errno-related errors with perror(). - * Ansify and Posixate. Add support for ISO 8859. - * Use better hash function. - * - * Revision 4.6 89/05/01 15:13:07 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.5 88/08/28 15:01:12 eggert - * Don't loop when writing error messages to a full filesystem. - * Flush stderr/stdout when mixing output. - * Yield exit status compatible with diff(1). - * Shrink stdio code size; allow cc -R; remove lint. - * - * Revision 4.4 87/12/18 11:44:47 narten - * fixed to use "varargs" in "fprintf"; this is required if it is to - * work on a SPARC machine such as a Sun-4 - * - * Revision 4.3 87/10/18 10:37:18 narten - * Updating version numbers. Changes relative to 1.1 actually relative - * to version 4.1 - * - * Revision 1.3 87/09/24 14:00:17 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:33 jenkins - * Port to suns - * - * Revision 4.1 83/03/25 18:12:51 wft - * Only changed $Header to $Id. - * - * Revision 3.3 82/12/10 16:22:37 wft - * Improved error messages, changed exit status on error to 1. - * - * Revision 3.2 82/11/28 21:27:10 wft - * Renamed ctab to map and included EOFILE; ctab is now a macro in rcsbase.h. - * Added fflsbuf(), fputs(), and fprintf(), which abort the RCS operations - * properly in case there is an IO-error (e.g., file system full). - * - * Revision 3.1 82/10/11 19:43:56 wft - * removed unused label out:; - * made sure all calls to getc() return into an integer, not a char. - */ - - -/* -#define LEXDB -*/ -/* version LEXDB is for testing the lexical analyzer. The testprogram - * reads a stream of lexemes, enters the revision numbers into the - * hashtable, and prints the recognized tokens. Keywords are recognized - * as identifiers. - */ - - - -#include "rcsbase.h" - -libId(lexId, "$FreeBSD$") - -static char *checkidentifier P((char*,int,int)); -static void errsay P((char const*)); -static void fatsay P((char const*)); -static void lookup P((char const*)); -static void startsay P((const char*,const char*)); -static void warnsay P((char const*)); - -static struct hshentry *nexthsh; /*pointer to next hash entry, set by lookup*/ - -enum tokens nexttok; /*next token, set by nextlex */ - -int hshenter; /*if true, next suitable lexeme will be entered */ - /*into the symbol table. Handle with care. */ -int nextc; /*next input character, initialized by Lexinit */ - -long rcsline; /*current line-number of input */ -int nerror; /*counter for errors */ -int quietflag; /*indicates quiet mode */ -RILE * finptr; /*input file descriptor */ - -FILE * frewrite; /*file descriptor for echoing input */ - -FILE * foutptr; /* copy of frewrite, but 0 to suppress echo */ - -static struct buf tokbuf; /* token buffer */ - -char const * NextString; /* next token */ - -/* - * Our hash algorithm is h[0] = 0, h[i+1] = 4*h[i] + c, - * so hshsize should be odd. - * See B J McKenzie, R Harries & T Bell, Selecting a hashing algorithm, - * Software--practice & experience 20, 2 (Feb 1990), 209-224. - */ -#ifndef hshsize -# define hshsize 511 -#endif - -static struct hshentry *hshtab[hshsize]; /*hashtable */ - -static int ignored_phrases; /* have we ignored phrases in this RCS file? */ - - void -warnignore() -{ - if (!ignored_phrases) { - ignored_phrases = true; - rcswarn("Unknown phrases like `%s ...;' are present.", NextString); - } -} - - - - static void -lookup(str) - char const *str; -/* Function: Looks up the character string pointed to by str in the - * hashtable. If the string is not present, a new entry for it is created. - * In any case, the address of the corresponding hashtable entry is placed - * into nexthsh. - */ -{ - register unsigned ihash; /* index into hashtable */ - register char const *sp; - register struct hshentry *n, **p; - - /* calculate hash code */ - sp = str; - ihash = 0; - while (*sp) - ihash = (ihash<<2) + *sp++; - ihash %= hshsize; - - for (p = &hshtab[ihash]; ; p = &n->nexthsh) - if (!(n = *p)) { - /* empty slot found */ - *p = n = ftalloc(struct hshentry); - n->num = fstr_save(str); - n->nexthsh = 0; -# ifdef LEXDB - VOID printf("\nEntered: %s at %u ", str, ihash); -# endif - break; - } else if (strcmp(str, n->num) == 0) - /* match found */ - break; - nexthsh = n; - NextString = n->num; -} - - - - - - - void -Lexinit() -/* Function: Initialization of lexical analyzer: - * initializes the hashtable, - * initializes nextc, nexttok if finptr != 0 - */ -{ register int c; - - for (c = hshsize; 0 <= --c; ) { - hshtab[c] = 0; - } - - nerror = 0; - if (finptr) { - foutptr = 0; - hshenter = true; - ignored_phrases = false; - rcsline = 1; - bufrealloc(&tokbuf, 2); - Iget_(finptr, nextc) - nextlex(); /*initial token*/ - } -} - - - - - - - - void -nextlex() - -/* Function: Reads the next token and sets nexttok to the next token code. - * Only if hshenter is set, a revision number is entered into the - * hashtable and a pointer to it is placed into nexthsh. - * This is useful for avoiding that dates are placed into the hashtable. - * For ID's and NUM's, NextString is set to the character string. - * Assumption: nextc contains the next character. - */ -{ register c; - declarecache; - register FILE *frew; - register char * sp; - char const *limit; - register enum tokens d; - register RILE *fin; - - fin=finptr; frew=foutptr; - setupcache(fin); cache(fin); - c = nextc; - - for (;;) { switch ((d = ctab[c])) { - - default: - fatserror("unknown character `%c'", c); - /*NOTREACHED*/ - - case NEWLN: - ++rcsline; -# ifdef LEXDB - afputc('\n',stdout); -# endif - /* Note: falls into next case */ - - case SPACE: - GETC_(frew, c) - continue; - - case IDCHAR: - case LETTER: - case Letter: - d = ID; - /* fall into */ - case DIGIT: - case PERIOD: - sp = tokbuf.string; - limit = sp + tokbuf.size; - *sp++ = c; - for (;;) { - GETC_(frew, c) - switch (ctab[c]) { - case IDCHAR: - case LETTER: - case Letter: - d = ID; - /* fall into */ - case DIGIT: - case PERIOD: - *sp++ = c; - if (limit <= sp) - sp = bufenlarge(&tokbuf, &limit); - continue; - - default: - break; - } - break; - } - *sp = 0; - if (d == DIGIT || d == PERIOD) { - d = NUM; - if (hshenter) { - lookup(tokbuf.string); - break; - } - } - NextString = fstr_save(tokbuf.string); - break; - - case SBEGIN: /* long string */ - d = STRING; - /* note: only the initial SBEGIN has been read*/ - /* read the string, and reset nextc afterwards*/ - break; - - case COLON: - case SEMI: - GETC_(frew, c) - break; - } break; } - nextc = c; - nexttok = d; - uncache(fin); -} - - int -eoflex() -/* - * Yield true if we look ahead to the end of the input, false otherwise. - * nextc becomes undefined at end of file. - */ -{ - register int c; - declarecache; - register FILE *fout; - register RILE *fin; - - c = nextc; - fin = finptr; - fout = foutptr; - setupcache(fin); cache(fin); - - for (;;) { - switch (ctab[c]) { - default: - nextc = c; - uncache(fin); - return false; - - case NEWLN: - ++rcsline; - /* fall into */ - case SPACE: - cachegeteof_(c, {uncache(fin);return true;}) - break; - } - if (fout) - aputc_(c, fout) - } -} - - -int getlex(token) -enum tokens token; -/* Function: Checks if nexttok is the same as token. If so, - * advances the input by calling nextlex and returns true. - * otherwise returns false. - * Doesn't work for strings and keywords; loses the character string for ids. - */ -{ - if (nexttok==token) { - nextlex(); - return(true); - } else return(false); -} - - int -getkeyopt(key) - char const *key; -/* Function: If the current token is a keyword identical to key, - * advances the input by calling nextlex and returns true; - * otherwise returns false. - */ -{ - if (nexttok==ID && strcmp(key,NextString) == 0) { - /* match found */ - ffree1(NextString); - nextlex(); - return(true); - } - return(false); -} - - void -getkey(key) - char const *key; -/* Check that the current input token is a keyword identical to key, - * and advance the input by calling nextlex. - */ -{ - if (!getkeyopt(key)) - fatserror("missing '%s' keyword", key); -} - - void -getkeystring(key) - char const *key; -/* Check that the current input token is a keyword identical to key, - * and advance the input by calling nextlex; then look ahead for a string. - */ -{ - getkey(key); - if (nexttok != STRING) - fatserror("missing string after '%s' keyword", key); -} - - - char const * -getid() -/* Function: Checks if nexttok is an identifier. If so, - * advances the input by calling nextlex and returns a pointer - * to the identifier; otherwise returns 0. - * Treats keywords as identifiers. - */ -{ - register char const *name; - if (nexttok==ID) { - name = NextString; - nextlex(); - return name; - } else - return 0; -} - - -struct hshentry * getnum() -/* Function: Checks if nexttok is a number. If so, - * advances the input by calling nextlex and returns a pointer - * to the hashtable entry. Otherwise returns 0. - * Doesn't work if hshenter is false. - */ -{ - register struct hshentry * num; - if (nexttok==NUM) { - num=nexthsh; - nextlex(); - return num; - } else - return 0; -} - - struct cbuf -getphrases(key) - char const *key; -/* -* Get a series of phrases that do not start with KEY. Yield resulting buffer. -* Stop when the next phrase starts with a token that is not an identifier, -* or is KEY. Copy input to foutptr if it is set. Unlike ignorephrases(), -* this routine assumes nextlex() has already been invoked before we start. -*/ -{ - declarecache; - register int c; - register char const *kn; - struct cbuf r; - register RILE *fin; - register FILE *frew; -# if large_memory -# define savech_(c) ; -# else - register char *p; - char const *limit; - struct buf b; -# define savech_(c) {if (limit<=p)p=bufenlarge(&b,&limit); *p++ =(c);} -# endif - - if (nexttok!=ID || strcmp(NextString,key) == 0) - clear_buf(&r); - else { - warnignore(); - fin = finptr; - frew = foutptr; - setupcache(fin); cache(fin); -# if large_memory - r.string = (char const*)cacheptr() - strlen(NextString) - 1; -# else - bufautobegin(&b); - bufscpy(&b, NextString); - p = b.string + strlen(b.string); - limit = b.string + b.size; -# endif - ffree1(NextString); - c = nextc; - for (;;) { - for (;;) { - savech_(c) - switch (ctab[c]) { - default: - fatserror("unknown character `%c'", c); - /*NOTREACHED*/ - case NEWLN: - ++rcsline; - /* fall into */ - case COLON: case DIGIT: case LETTER: case Letter: - case PERIOD: case SPACE: - GETC_(frew, c) - continue; - case SBEGIN: /* long string */ - for (;;) { - for (;;) { - GETC_(frew, c) - savech_(c) - switch (c) { - case '\n': - ++rcsline; - /* fall into */ - default: - continue; - - case SDELIM: - break; - } - break; - } - GETC_(frew, c) - if (c != SDELIM) - break; - savech_(c) - } - continue; - case SEMI: - cacheget_(c) - if (ctab[c] == NEWLN) { - if (frew) - aputc_(c, frew) - ++rcsline; - savech_(c) - cacheget_(c) - } -# if large_memory - r.size = (char const*)cacheptr() - 1 - r.string; -# endif - for (;;) { - switch (ctab[c]) { - case NEWLN: - ++rcsline; - /* fall into */ - case SPACE: - cacheget_(c) - continue; - - default: break; - } - break; - } - if (frew) - aputc_(c, frew) - break; - } - break; - } - if (ctab[c] == Letter) { - for (kn = key; c && *kn==c; kn++) - GETC_(frew, c) - if (!*kn) - switch (ctab[c]) { - case DIGIT: case LETTER: case Letter: - case IDCHAR: case PERIOD: - break; - default: - nextc = c; - NextString = fstr_save(key); - nexttok = ID; - uncache(fin); - goto returnit; - } -# if !large_memory - { - register char const *ki; - for (ki=key; ki<kn; ) - savech_(*ki++) - } -# endif - } else { - nextc = c; - uncache(fin); - nextlex(); - break; - } - } - returnit:; -# if !large_memory - return bufremember(&b, (size_t)(p - b.string)); -# endif - } - return r; -} - - - void -readstring() -/* skip over characters until terminating single SDELIM */ -/* If foutptr is set, copy every character read to foutptr. */ -/* Does not advance nextlex at the end. */ -{ register c; - declarecache; - register FILE *frew; - register RILE *fin; - fin=finptr; frew=foutptr; - setupcache(fin); cache(fin); - for (;;) { - GETC_(frew, c) - switch (c) { - case '\n': - ++rcsline; - break; - - case SDELIM: - GETC_(frew, c) - if (c != SDELIM) { - /* end of string */ - nextc = c; - uncache(fin); - return; - } - break; - } - } -} - - - void -printstring() -/* Function: copy a string to stdout, until terminated with a single SDELIM. - * Does not advance nextlex at the end. - */ -{ - register c; - declarecache; - register FILE *fout; - register RILE *fin; - fin=finptr; - fout = stdout; - setupcache(fin); cache(fin); - for (;;) { - cacheget_(c) - switch (c) { - case '\n': - ++rcsline; - break; - case SDELIM: - cacheget_(c) - if (c != SDELIM) { - nextc=c; - uncache(fin); - return; - } - break; - } - aputc_(c,fout) - } -} - - - - struct cbuf -savestring(target) - struct buf *target; -/* Copies a string terminated with SDELIM from file finptr to buffer target. - * Double SDELIM is replaced with SDELIM. - * If foutptr is set, the string is also copied unchanged to foutptr. - * Does not advance nextlex at the end. - * Yield a copy of *TARGET, except with exact length. - */ -{ - register c; - declarecache; - register FILE *frew; - register char *tp; - register RILE *fin; - char const *limit; - struct cbuf r; - - fin=finptr; frew=foutptr; - setupcache(fin); cache(fin); - tp = target->string; limit = tp + target->size; - for (;;) { - GETC_(frew, c) - switch (c) { - case '\n': - ++rcsline; - break; - case SDELIM: - GETC_(frew, c) - if (c != SDELIM) { - /* end of string */ - nextc=c; - r.string = target->string; - r.size = tp - r.string; - uncache(fin); - return r; - } - break; - } - if (tp == limit) - tp = bufenlarge(target, &limit); - *tp++ = c; - } -} - - - static char * -checkidentifier(id, delimiter, dotok) - register char *id; - int delimiter; - register int dotok; -/* Function: check whether the string starting at id is an */ -/* identifier and return a pointer to the delimiter*/ -/* after the identifier. White space, delim and 0 */ -/* are legal delimiters. Aborts the program if not*/ -/* a legal identifier. Useful for checking commands*/ -/* If !delim, the only delimiter is 0. */ -/* Allow '.' in identifier only if DOTOK is set. */ -{ - register char *temp; - register char c; - register char delim = delimiter; - int isid = false; - - temp = id; - for (;; id++) { - switch (ctab[(unsigned char)(c = *id)]) { - case IDCHAR: - case LETTER: - case Letter: - isid = true; - continue; - - case DIGIT: - continue; - - case PERIOD: - if (dotok) - continue; - break; - - default: - break; - } - break; - } - if ( ! isid - || (c && (!delim || (c!=delim && c!=' ' && c!='\t' && c!='\n'))) - ) { - /* append \0 to end of id before error message */ - while ((c = *id) && c!=' ' && c!='\t' && c!='\n' && c!=delim) - id++; - *id = '\0'; - faterror("invalid %s `%s'", - dotok ? "identifier" : "symbol", temp - ); - } - return id; -} - - char * -checkid(id, delimiter) - char *id; - int delimiter; -{ - return checkidentifier(id, delimiter, true); -} - - char * -checksym(sym, delimiter) - char *sym; - int delimiter; -{ - return checkidentifier(sym, delimiter, false); -} - - void -checksid(id) - char *id; -/* Check whether the string ID is an identifier. */ -{ - VOID checkid(id, 0); -} - - void -checkssym(sym) - char *sym; -{ - VOID checksym(sym, 0); -} - - -#if !large_memory -# define Iclose(f) fclose(f) -#else -# if !maps_memory - static int Iclose P((RILE *)); - static int - Iclose(f) - register RILE *f; - { - tfree(f->base); - f->base = 0; - return fclose(f->stream); - } -# else - static int Iclose P((RILE *)); - static int - Iclose(f) - register RILE *f; - { - (* f->deallocate) (f); - f->base = 0; - return close(f->fd); - } - -# if has_map_fd - static void map_fd_deallocate P((RILE *)); - static void - map_fd_deallocate(f) - register RILE *f; - { - if (vm_deallocate( - task_self(), - (vm_address_t) f->base, - (vm_size_t) (f->lim - f->base) - ) != KERN_SUCCESS) - efaterror("vm_deallocate"); - } -# endif -# if has_mmap - static void mmap_deallocate P((RILE *)); - static void - mmap_deallocate(f) - register RILE *f; - { - if (munmap((char *) f->base, (size_t) (f->lim - f->base)) != 0) - efaterror("munmap"); - } -# endif - static void read_deallocate P((RILE *)); - static void - read_deallocate(f) - RILE *f; - { - tfree(f->base); - } - - static void nothing_to_deallocate P((RILE *)); - static void - nothing_to_deallocate(f) - RILE *f; - { - } -# endif -#endif - - -#if large_memory && maps_memory - static RILE *fd2_RILE P((int,char const*,struct stat*)); - static RILE * -fd2_RILE(fd, name, status) -#else - static RILE *fd2RILE P((int,char const*,char const*,struct stat*)); - static RILE * -fd2RILE(fd, name, type, status) - char const *type; -#endif - int fd; - char const *name; - register struct stat *status; -{ - struct stat st; - - if (!status) - status = &st; - if (fstat(fd, status) != 0) - efaterror(name); - if (!S_ISREG(status->st_mode)) { - error("`%s' is not a regular file", name); - VOID close(fd); - errno = EINVAL; - return 0; - } else { - -# if !(large_memory && maps_memory) - FILE *stream; - if (!(stream = fdopen(fd, type))) - efaterror(name); -# endif - -# if !large_memory - return stream; -# else -# define RILES 3 - { - static RILE rilebuf[RILES]; - - register RILE *f; - size_t s = status->st_size; - - if (s != status->st_size) - faterror("%s: too large", name); - for (f = rilebuf; f->base; f++) - if (f == rilebuf+RILES) - faterror("too many RILEs"); -# if maps_memory - f->deallocate = nothing_to_deallocate; -# endif - if (!s) { - static unsigned char nothing; - f->base = ¬hing; /* Any nonzero address will do. */ - } else { - f->base = 0; -# if has_map_fd - map_fd( - fd, (vm_offset_t)0, (vm_address_t*) &f->base, - TRUE, (vm_size_t)s - ); - f->deallocate = map_fd_deallocate; -# endif -# if has_mmap - if (!f->base) { - catchmmapints(); - f->base = (unsigned char *) mmap( - (char *)0, s, PROT_READ, MAP_SHARED, - fd, (off_t)0 - ); -# ifndef MAP_FAILED -# define MAP_FAILED (-1) -# endif - if (f->base == (unsigned char *) MAP_FAILED) - f->base = 0; - else { -# if has_NFS && mmap_signal - /* - * On many hosts, the superuser - * can mmap an NFS file it can't read. - * So access the first page now, and print - * a nice message if a bus error occurs. - */ - readAccessFilenameBuffer(name, f->base); -# endif - } - f->deallocate = mmap_deallocate; - } -# endif - if (!f->base) { - f->base = tnalloc(unsigned char, s); -# if maps_memory - { - /* - * We can't map the file into memory for some reason. - * Read it into main memory all at once; this is - * the simplest substitute for memory mapping. - */ - char *bufptr = (char *) f->base; - size_t bufsiz = s; - do { - ssize_t r = read(fd, bufptr, bufsiz); - switch (r) { - case -1: - efaterror(name); - - case 0: - /* The file must have shrunk! */ - status->st_size = s -= bufsiz; - bufsiz = 0; - break; - - default: - bufptr += r; - bufsiz -= r; - break; - } - } while (bufsiz); - if (lseek(fd, (off_t)0, SEEK_SET) == -1) - efaterror(name); - f->deallocate = read_deallocate; - } -# endif - } - } - f->ptr = f->base; - f->lim = f->base + s; - f->fd = fd; -# if !maps_memory - f->readlim = f->base; - f->stream = stream; -# endif - if_advise_access(s, f, MADV_SEQUENTIAL); - return f; - } -# endif - } -} - -#if !maps_memory && large_memory - int -Igetmore(f) - register RILE *f; -{ - register fread_type r; - register size_t s = f->lim - f->readlim; - - if (BUFSIZ < s) - s = BUFSIZ; - if (!(r = Fread(f->readlim, sizeof(*f->readlim), s, f->stream))) { - testIerror(f->stream); - f->lim = f->readlim; /* The file might have shrunk! */ - return 0; - } - f->readlim += r; - return 1; -} -#endif - -#if has_madvise && has_mmap && large_memory - void -advise_access(f, advice) - register RILE *f; - int advice; -{ - if (f->deallocate == mmap_deallocate) - VOID madvise((char *)f->base, (size_t)(f->lim - f->base), advice); - /* Don't worry if madvise fails; it's only advisory. */ -} -#endif - - RILE * -#if large_memory && maps_memory -I_open(name, status) -#else -Iopen(name, type, status) - char const *type; -#endif - char const *name; - struct stat *status; -/* Open NAME for reading, yield its descriptor, and set *STATUS. */ -{ - int fd = fdSafer(open(name, O_RDONLY -# if OPEN_O_BINARY - | (strchr(type,'b') ? OPEN_O_BINARY : 0) -# endif - )); - - if (fd < 0) - return 0; -# if large_memory && maps_memory - return fd2_RILE(fd, name, status); -# else - return fd2RILE(fd, name, type, status); -# endif -} - - -static int Oerrloop; - - void -Oerror() -{ - if (Oerrloop) - exiterr(); - Oerrloop = true; - efaterror("output error"); -} - -void Ieof() { fatserror("unexpected end of file"); } -void Ierror() { efaterror("input error"); } -void testIerror(f) FILE *f; { if (ferror(f)) Ierror(); } -void testOerror(o) FILE *o; { if (ferror(o)) Oerror(); } - -void Ifclose(f) RILE *f; { if (f && Iclose(f)!=0) Ierror(); } -void Ofclose(f) FILE *f; { if (f && fclose(f)!=0) Oerror(); } -void Izclose(p) RILE **p; { Ifclose(*p); *p = 0; } -void Ozclose(p) FILE **p; { Ofclose(*p); *p = 0; } - -#if !large_memory - void -testIeof(f) - FILE *f; -{ - testIerror(f); - if (feof(f)) - Ieof(); -} -void Irewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Ierror(); } -#endif - -void Orewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Oerror(); } - -void aflush(f) FILE *f; { if (fflush(f) != 0) Oerror(); } -void eflush() { if (fflush(stderr)!=0 && !Oerrloop) Oerror(); } -void oflush() -{ - if (fflush(workstdout ? workstdout : stdout) != 0 && !Oerrloop) - Oerror(); -} - - void -fatcleanup(already_newline) - int already_newline; -{ - VOID fprintf(stderr, already_newline+"\n%s aborted\n", cmdid); - exiterr(); -} - - static void -startsay(s, t) - const char *s, *t; -{ - oflush(); - if (s) - aprintf(stderr, "%s: %s: %s", cmdid, s, t); - else - aprintf(stderr, "%s: %s", cmdid, t); -} - - static void -fatsay(s) - char const *s; -{ - startsay(s, ""); -} - - static void -errsay(s) - char const *s; -{ - fatsay(s); - nerror++; -} - - static void -warnsay(s) - char const *s; -{ - startsay(s, "warning: "); -} - -void eerror(s) char const *s; { enerror(errno,s); } - - void -enerror(e,s) - int e; - char const *s; -{ - errsay((char const*)0); - errno = e; - perror(s); - eflush(); -} - -void efaterror(s) char const *s; { enfaterror(errno,s); } - - void -enfaterror(e,s) - int e; - char const *s; -{ - fatsay((char const*)0); - errno = e; - perror(s); - fatcleanup(true); -} - -#if has_prototypes - void -error(char const *format,...) -#else - /*VARARGS1*/ void error(format, va_alist) char const *format; va_dcl -#endif -/* non-fatal error */ -{ - va_list args; - errsay((char const*)0); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n',stderr); - eflush(); -} - -#if has_prototypes - void -rcserror(char const *format,...) -#else - /*VARARGS1*/ void rcserror(format, va_alist) char const *format; va_dcl -#endif -/* non-fatal RCS file error */ -{ - va_list args; - errsay(RCSname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n',stderr); - eflush(); -} - -#if has_prototypes - void -workerror(char const *format,...) -#else - /*VARARGS1*/ void workerror(format, va_alist) char const *format; va_dcl -#endif -/* non-fatal working file error */ -{ - va_list args; - errsay(workname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n',stderr); - eflush(); -} - -#if has_prototypes - void -fatserror(char const *format,...) -#else - /*VARARGS1*/ void - fatserror(format, va_alist) char const *format; va_dcl -#endif -/* fatal RCS file syntax error */ -{ - va_list args; - oflush(); - VOID fprintf(stderr, "%s: %s:%ld: ", cmdid, RCSname, rcsline); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - fatcleanup(false); -} - -#if has_prototypes - void -faterror(char const *format,...) -#else - /*VARARGS1*/ void faterror(format, va_alist) - char const *format; va_dcl -#endif -/* fatal error, terminates program after cleanup */ -{ - va_list args; - fatsay((char const*)0); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - fatcleanup(false); -} - -#if has_prototypes - void -rcsfaterror(char const *format,...) -#else - /*VARARGS1*/ void rcsfaterror(format, va_alist) - char const *format; va_dcl -#endif -/* fatal RCS file error, terminates program after cleanup */ -{ - va_list args; - fatsay(RCSname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - fatcleanup(false); -} - -#if has_prototypes - void -warn(char const *format,...) -#else - /*VARARGS1*/ void warn(format, va_alist) char const *format; va_dcl -#endif -/* warning */ -{ - va_list args; - if (!quietflag) { - warnsay((char *)0); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n', stderr); - eflush(); - } -} - -#if has_prototypes - void -rcswarn(char const *format,...) -#else - /*VARARGS1*/ void rcswarn(format, va_alist) char const *format; va_dcl -#endif -/* RCS file warning */ -{ - va_list args; - if (!quietflag) { - warnsay(RCSname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n', stderr); - eflush(); - } -} - -#if has_prototypes - void -workwarn(char const *format,...) -#else - /*VARARGS1*/ void workwarn(format, va_alist) char const *format; va_dcl -#endif -/* working file warning */ -{ - va_list args; - if (!quietflag) { - warnsay(workname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n', stderr); - eflush(); - } -} - - void -redefined(c) - int c; -{ - warn("redefinition of -%c option", c); -} - -#if has_prototypes - void -diagnose(char const *format,...) -#else - /*VARARGS1*/ void diagnose(format, va_alist) char const *format; va_dcl -#endif -/* prints a diagnostic message */ -/* Unlike the other routines, it does not append a newline. */ -/* This lets some callers suppress the newline, and is faster */ -/* in implementations that flush stderr just at the end of each printf. */ -{ - va_list args; - if (!quietflag) { - oflush(); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - eflush(); - } -} - - - - void -afputc(c, f) -/* afputc(c,f); acts like aputc_(c,f) but is smaller and slower. */ - int c; - register FILE *f; -{ - aputc_(c,f) -} - - - void -aputs(s, iop) - char const *s; - FILE *iop; -/* Function: Put string s on file iop, abort on error. - */ -{ -#if has_fputs - if (fputs(s, iop) < 0) - Oerror(); -#else - awrite(s, strlen(s), iop); -#endif -} - - - - void -#if has_prototypes -fvfprintf(FILE *stream, char const *format, va_list args) -#else - fvfprintf(stream,format,args) FILE *stream; char *format; va_list args; -#endif -/* like vfprintf, except abort program on error */ -{ -#if has_vfprintf - if (vfprintf(stream, format, args) < 0) - Oerror(); -#else -# if has__doprintf - _doprintf(stream, format, args); -# else -# if has__doprnt - _doprnt(format, args, stream); -# else - int *a = (int *)args; - VOID fprintf(stream, format, - a[0], a[1], a[2], a[3], a[4], - a[5], a[6], a[7], a[8], a[9] - ); -# endif -# endif - if (ferror(stream)) - Oerror(); -#endif -} - -#if has_prototypes - void -aprintf(FILE *iop, char const *fmt, ...) -#else - /*VARARGS2*/ void -aprintf(iop, fmt, va_alist) -FILE *iop; -char const *fmt; -va_dcl -#endif -/* Function: formatted output. Same as fprintf in stdio, - * but aborts program on error - */ -{ - va_list ap; - vararg_start(ap, fmt); - fvfprintf(iop, fmt, ap); - va_end(ap); -} - - - -#ifdef LEXDB -/* test program reading a stream of lexemes and printing the tokens. - */ - - - - int -main(argc,argv) -int argc; char * argv[]; -{ - cmdid="lextest"; - if (argc<2) { - aputs("No input file\n",stderr); - exitmain(EXIT_FAILURE); - } - if (!(finptr=Iopen(argv[1], FOPEN_R, (struct stat*)0))) { - faterror("can't open input file %s",argv[1]); - } - Lexinit(); - while (!eoflex()) { - switch (nexttok) { - - case ID: - VOID printf("ID: %s",NextString); - break; - - case NUM: - if (hshenter) - VOID printf("NUM: %s, index: %d",nexthsh->num, nexthsh-hshtab); - else - VOID printf("NUM, unentered: %s",NextString); - hshenter = !hshenter; /*alternate between dates and numbers*/ - break; - - case COLON: - VOID printf("COLON"); break; - - case SEMI: - VOID printf("SEMI"); break; - - case STRING: - readstring(); - VOID printf("STRING"); break; - - case UNKN: - VOID printf("UNKN"); break; - - default: - VOID printf("DEFAULT"); break; - } - VOID printf(" | "); - nextlex(); - } - exitmain(EXIT_SUCCESS); -} - -void exiterr() { _exit(EXIT_FAILURE); } - - -#endif diff --git a/gnu/usr.bin/rcs/lib/rcsmap.c b/gnu/usr.bin/rcs/lib/rcsmap.c deleted file mode 100644 index 89fb08d..0000000 --- a/gnu/usr.bin/rcs/lib/rcsmap.c +++ /dev/null @@ -1,69 +0,0 @@ -/* RCS map of character types */ - -/* Copyright (C) 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1995 by Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#include "rcsbase.h" - -libId(mapId, "$FreeBSD$") - -/* map of character types */ -/* ISO 8859/1 (Latin-1) */ -enum tokens const ctab[] = { - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - SPACE, SPACE, NEWLN, SPACE, SPACE, SPACE, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - SPACE, IDCHAR, IDCHAR, IDCHAR, DELIM, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, DELIM, IDCHAR, PERIOD, IDCHAR, - DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, - DIGIT, DIGIT, COLON, SEMI, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - SBEGIN, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, IDCHAR, IDCHAR, IDCHAR, IDCHAR, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, IDCHAR, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, IDCHAR, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter -}; diff --git a/gnu/usr.bin/rcs/lib/rcsrev.c b/gnu/usr.bin/rcs/lib/rcsrev.c deleted file mode 100644 index 12c6c43..0000000 --- a/gnu/usr.bin/rcs/lib/rcsrev.c +++ /dev/null @@ -1,911 +0,0 @@ -/* Handle RCS revision numbers. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.10 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.9 1995/06/01 16:23:43 eggert - * (cmpdate, normalizeyear): New functions work around MKS RCS incompatibility. - * (cmpnum, compartial): s[d] -> *(s+d) to work around Cray compiler bug. - * (genrevs, genbranch): cmpnum -> cmpdate - * - * Revision 5.8 1994/03/17 14:05:48 eggert - * Remove lint. - * - * Revision 5.7 1993/11/09 17:40:15 eggert - * Fix format string typos. - * - * Revision 5.6 1993/11/03 17:42:27 eggert - * Revision number `.N' now stands for `D.N', where D is the default branch. - * Add -z. Improve quality of diagnostics. Add `namedrev' for Name support. - * - * Revision 5.5 1992/07/28 16:12:44 eggert - * Identifiers may now start with a digit. Avoid `unsigned'. - * - * Revision 5.4 1992/01/06 02:42:34 eggert - * while (E) ; -> while (E) continue; - * - * Revision 5.3 1991/08/19 03:13:55 eggert - * Add `-r$', `-rB.'. Remove botches like `<now>' from messages. Tune. - * - * Revision 5.2 1991/04/21 11:58:28 eggert - * Add tiprev(). - * - * Revision 5.1 1991/02/25 07:12:43 eggert - * Avoid overflow when comparing revision numbers. - * - * Revision 5.0 1990/08/22 08:13:43 eggert - * Remove compile-time limits; use malloc instead. - * Ansify and Posixate. Tune. - * Remove possibility of an internal error. Remove lint. - * - * Revision 4.5 89/05/01 15:13:22 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.4 87/12/18 11:45:22 narten - * more lint cleanups. Also, the NOTREACHED comment is no longer necessary, - * since there's now a return value there with a value. (Guy Harris) - * - * Revision 4.3 87/10/18 10:38:42 narten - * Updating version numbers. Changes relative to version 1.1 actually - * relative to 4.1 - * - * Revision 1.3 87/09/24 14:00:37 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:37 jenkins - * Port to suns - * - * Revision 4.1 83/03/25 21:10:45 wft - * Only changed $Header to $Id. - * - * Revision 3.4 82/12/04 13:24:08 wft - * Replaced getdelta() with gettree(). - * - * Revision 3.3 82/11/28 21:33:15 wft - * fixed compartial() and compnum() for nil-parameters; fixed nils - * in error messages. Testprogram output shortenend. - * - * Revision 3.2 82/10/18 21:19:47 wft - * renamed compnum->cmpnum, compnumfld->cmpnumfld, - * numericrevno->numricrevno. - * - * Revision 3.1 82/10/11 19:46:09 wft - * changed expandsym() to check for source==nil; returns zero length string - * in that case. - */ - -#include "rcsbase.h" - -libId(revId, "$FreeBSD$") - -static char const *branchtip P((char const*)); -static char const *lookupsym P((char const*)); -static char const *normalizeyear P((char const*,char[5])); -static struct hshentry *genbranch P((struct hshentry const*,char const*,int,char const*,char const*,char const*,struct hshentries**)); -static void absent P((char const*,int)); -static void cantfindbranch P((char const*,char const[datesize],char const*,char const*)); -static void store1 P((struct hshentries***,struct hshentry*)); - - - - int -countnumflds(s) - char const *s; -/* Given a pointer s to a dotted number (date or revision number), - * countnumflds returns the number of digitfields in s. - */ -{ - register char const *sp; - register int count; - if (!(sp=s) || !*sp) - return 0; - count = 1; - do { - if (*sp++ == '.') count++; - } while (*sp); - return(count); -} - - void -getbranchno(revno,branchno) - char const *revno; - struct buf *branchno; -/* Given a revision number revno, getbranchno copies the number of the branch - * on which revno is into branchno. If revno itself is a branch number, - * it is copied unchanged. - */ -{ - register int numflds; - register char *tp; - - bufscpy(branchno, revno); - numflds=countnumflds(revno); - if (!(numflds & 1)) { - tp = branchno->string; - while (--numflds) - while (*tp++ != '.') - continue; - *(tp-1)='\0'; - } -} - - - -int cmpnum(num1, num2) - char const *num1, *num2; -/* compares the two dotted numbers num1 and num2 lexicographically - * by field. Individual fields are compared numerically. - * returns <0, 0, >0 if num1<num2, num1==num2, and num1>num2, resp. - * omitted fields are assumed to be higher than the existing ones. -*/ -{ - register char const *s1, *s2; - register size_t d1, d2; - register int r; - - s1 = num1 ? num1 : ""; - s2 = num2 ? num2 : ""; - - for (;;) { - /* Give precedence to shorter one. */ - if (!*s1) - return (unsigned char)*s2; - if (!*s2) - return -1; - - /* Strip leading zeros, then find number of digits. */ - while (*s1=='0') ++s1; - while (*s2=='0') ++s2; - for (d1=0; isdigit(*(s1+d1)); d1++) continue; - for (d2=0; isdigit(*(s2+d2)); d2++) continue; - - /* Do not convert to integer; it might overflow! */ - if (d1 != d2) - return d1<d2 ? -1 : 1; - if ((r = memcmp(s1, s2, d1))) - return r; - s1 += d1; - s2 += d1; - - /* skip '.' */ - if (*s1) s1++; - if (*s2) s2++; - } -} - - - -int cmpnumfld(num1, num2, fld) - char const *num1, *num2; - int fld; -/* Compare the two dotted numbers at field fld. - * num1 and num2 must have at least fld fields. - * fld must be positive. -*/ -{ - register char const *s1, *s2; - register size_t d1, d2; - - s1 = num1; - s2 = num2; - /* skip fld-1 fields */ - while (--fld) { - while (*s1++ != '.') - continue; - while (*s2++ != '.') - continue; - } - /* Now s1 and s2 point to the beginning of the respective fields */ - while (*s1=='0') ++s1; for (d1=0; isdigit(*(s1+d1)); d1++) continue; - while (*s2=='0') ++s2; for (d2=0; isdigit(*(s2+d2)); d2++) continue; - - return d1<d2 ? -1 : d1==d2 ? memcmp(s1,s2,d1) : 1; -} - - - int -cmpdate(d1, d2) - char const *d1, *d2; -/* -* Compare the two dates. This is just like cmpnum, -* except that for compatibility with old versions of RCS, -* 1900 is added to dates with two-digit years. -*/ -{ - char year1[5], year2[5]; - int r = cmpnumfld(normalizeyear(d1,year1), normalizeyear(d2,year2), 1); - - if (r) - return r; - else { - while (isdigit(*d1)) d1++; d1 += *d1=='.'; - while (isdigit(*d2)) d2++; d2 += *d2=='.'; - return cmpnum(d1, d2); - } -} - - static char const * -normalizeyear(date, year) - char const *date; - char year[5]; -{ - if (isdigit(date[0]) && isdigit(date[1]) && !isdigit(date[2])) { - year[0] = '1'; - year[1] = '9'; - year[2] = date[0]; - year[3] = date[1]; - year[4] = 0; - return year; - } else - return date; -} - - - static void -cantfindbranch(revno, date, author, state) - char const *revno, date[datesize], *author, *state; -{ - char datebuf[datesize + zonelenmax]; - - rcserror("No revision on branch %s has%s%s%s%s%s%s.", - revno, - date ? " a date before " : "", - date ? date2str(date,datebuf) : "", - author ? " and author "+(date?0:4) : "", - author ? author : "", - state ? " and state "+(date||author?0:4) : "", - state ? state : "" - ); -} - - static void -absent(revno, field) - char const *revno; - int field; -{ - struct buf t; - bufautobegin(&t); - rcserror("%s %s absent", field&1?"revision":"branch", - partialno(&t,revno,field) - ); - bufautoend(&t); -} - - - int -compartial(num1, num2, length) - char const *num1, *num2; - int length; - -/* compare the first "length" fields of two dot numbers; - the omitted field is considered to be larger than any number */ -/* restriction: at least one number has length or more fields */ - -{ - register char const *s1, *s2; - register size_t d1, d2; - register int r; - - s1 = num1; s2 = num2; - if (!s1) return 1; - if (!s2) return -1; - - for (;;) { - if (!*s1) return 1; - if (!*s2) return -1; - - while (*s1=='0') ++s1; for (d1=0; isdigit(*(s1+d1)); d1++) continue; - while (*s2=='0') ++s2; for (d2=0; isdigit(*(s2+d2)); d2++) continue; - - if (d1 != d2) - return d1<d2 ? -1 : 1; - if ((r = memcmp(s1, s2, d1))) - return r; - if (!--length) - return 0; - - s1 += d1; - s2 += d1; - - if (*s1 == '.') s1++; - if (*s2 == '.') s2++; - } -} - - -char * partialno(rev1,rev2,length) - struct buf *rev1; - char const *rev2; - register int length; -/* Function: Copies length fields of revision number rev2 into rev1. - * Return rev1's string. - */ -{ - register char *r1; - - bufscpy(rev1, rev2); - r1 = rev1->string; - while (length) { - while (*r1!='.' && *r1) - ++r1; - ++r1; - length--; - } - /* eliminate last '.'*/ - *(r1-1)='\0'; - return rev1->string; -} - - - - - static void -store1(store, next) - struct hshentries ***store; - struct hshentry *next; -/* - * Allocate a new list node that addresses NEXT. - * Append it to the list that **STORE is the end pointer of. - */ -{ - register struct hshentries *p; - - p = ftalloc(struct hshentries); - p->first = next; - **store = p; - *store = &p->rest; -} - -struct hshentry * genrevs(revno,date,author,state,store) - char const *revno, *date, *author, *state; - struct hshentries **store; -/* Function: finds the deltas needed for reconstructing the - * revision given by revno, date, author, and state, and stores pointers - * to these deltas into a list whose starting address is given by store. - * The last delta (target delta) is returned. - * If the proper delta could not be found, 0 is returned. - */ -{ - int length; - register struct hshentry * next; - int result; - char const *branchnum; - struct buf t; - char datebuf[datesize + zonelenmax]; - - bufautobegin(&t); - - if (!(next = Head)) { - rcserror("RCS file empty"); - goto norev; - } - - length = countnumflds(revno); - - if (length >= 1) { - /* at least one field; find branch exactly */ - while ((result=cmpnumfld(revno,next->num,1)) < 0) { - store1(&store, next); - next = next->next; - if (!next) { - rcserror("branch number %s too low", partialno(&t,revno,1)); - goto norev; - } - } - - if (result>0) { - absent(revno, 1); - goto norev; - } - } - if (length<=1){ - /* pick latest one on given branch */ - branchnum = next->num; /* works even for empty revno*/ - while (next && - cmpnumfld(branchnum,next->num,1) == 0 && - ( - (date && cmpdate(date,next->date) < 0) || - (author && strcmp(author,next->author) != 0) || - (state && strcmp(state,next->state) != 0) - ) - ) - { - store1(&store, next); - next=next->next; - } - if (!next || - (cmpnumfld(branchnum,next->num,1)!=0))/*overshot*/ { - cantfindbranch( - length ? revno : partialno(&t,branchnum,1), - date, author, state - ); - goto norev; - } else { - store1(&store, next); - } - *store = 0; - return next; - } - - /* length >=2 */ - /* find revision; may go low if length==2*/ - while ((result=cmpnumfld(revno,next->num,2)) < 0 && - (cmpnumfld(revno,next->num,1)==0) ) { - store1(&store, next); - next = next->next; - if (!next) - break; - } - - if (!next || cmpnumfld(revno,next->num,1) != 0) { - rcserror("revision number %s too low", partialno(&t,revno,2)); - goto norev; - } - if ((length>2) && (result!=0)) { - absent(revno, 2); - goto norev; - } - - /* print last one */ - store1(&store, next); - - if (length>2) - return genbranch(next,revno,length,date,author,state,store); - else { /* length == 2*/ - if (date && cmpdate(date,next->date)<0) { - rcserror("Revision %s has date %s.", - next->num, - date2str(next->date, datebuf) - ); - return 0; - } - if (author && strcmp(author,next->author)!=0) { - rcserror("Revision %s has author %s.", - next->num, next->author - ); - return 0; - } - if (state && strcmp(state,next->state)!=0) { - rcserror("Revision %s has state %s.", - next->num, - next->state ? next->state : "<empty>" - ); - return 0; - } - *store = 0; - return next; - } - - norev: - bufautoend(&t); - return 0; -} - - - - - static struct hshentry * -genbranch(bpoint, revno, length, date, author, state, store) - struct hshentry const *bpoint; - char const *revno; - int length; - char const *date, *author, *state; - struct hshentries **store; -/* Function: given a branchpoint, a revision number, date, author, and state, - * genbranch finds the deltas necessary to reconstruct the given revision - * from the branch point on. - * Pointers to the found deltas are stored in a list beginning with store. - * revno must be on a side branch. - * Return 0 on error. - */ -{ - int field; - register struct hshentry * next, * trail; - register struct branchhead const *bhead; - int result; - struct buf t; - char datebuf[datesize + zonelenmax]; - - field = 3; - bhead = bpoint->branches; - - do { - if (!bhead) { - bufautobegin(&t); - rcserror("no side branches present for %s", - partialno(&t,revno,field-1) - ); - bufautoend(&t); - return 0; - } - - /*find branch head*/ - /*branches are arranged in increasing order*/ - while (0 < (result=cmpnumfld(revno,bhead->hsh->num,field))) { - bhead = bhead->nextbranch; - if (!bhead) { - bufautobegin(&t); - rcserror("branch number %s too high", - partialno(&t,revno,field) - ); - bufautoend(&t); - return 0; - } - } - - if (result<0) { - absent(revno, field); - return 0; - } - - next = bhead->hsh; - if (length==field) { - /* pick latest one on that branch */ - trail = 0; - do { if ((!date || cmpdate(date,next->date)>=0) && - (!author || strcmp(author,next->author)==0) && - (!state || strcmp(state,next->state)==0) - ) trail = next; - next=next->next; - } while (next); - - if (!trail) { - cantfindbranch(revno, date, author, state); - return 0; - } else { /* print up to last one suitable */ - next = bhead->hsh; - while (next!=trail) { - store1(&store, next); - next=next->next; - } - store1(&store, next); - } - *store = 0; - return next; - } - - /* length > field */ - /* find revision */ - /* check low */ - if (cmpnumfld(revno,next->num,field+1)<0) { - bufautobegin(&t); - rcserror("revision number %s too low", - partialno(&t,revno,field+1) - ); - bufautoend(&t); - return 0; - } - do { - store1(&store, next); - trail = next; - next = next->next; - } while (next && cmpnumfld(revno,next->num,field+1)>=0); - - if ((length>field+1) && /*need exact hit */ - (cmpnumfld(revno,trail->num,field+1) !=0)){ - absent(revno, field+1); - return 0; - } - if (length == field+1) { - if (date && cmpdate(date,trail->date)<0) { - rcserror("Revision %s has date %s.", - trail->num, - date2str(trail->date, datebuf) - ); - return 0; - } - if (author && strcmp(author,trail->author)!=0) { - rcserror("Revision %s has author %s.", - trail->num, trail->author - ); - return 0; - } - if (state && strcmp(state,trail->state)!=0) { - rcserror("Revision %s has state %s.", - trail->num, - trail->state ? trail->state : "<empty>" - ); - return 0; - } - } - bhead = trail->branches; - - } while ((field+=2) <= length); - *store = 0; - return trail; -} - - - static char const * -lookupsym(id) - char const *id; -/* Function: looks up id in the list of symbolic names starting - * with pointer SYMBOLS, and returns a pointer to the corresponding - * revision number. Return 0 if not present. - */ -{ - register struct assoc const *next; - for (next = Symbols; next; next = next->nextassoc) - if (strcmp(id, next->symbol)==0) - return next->num; - return 0; -} - -int expandsym(source, target) - char const *source; - struct buf *target; -/* Function: Source points to a revision number. Expandsym copies - * the number to target, but replaces all symbolic fields in the - * source number with their numeric values. - * Expand a branch followed by `.' to the latest revision on that branch. - * Ignore `.' after a revision. Remove leading zeros. - * returns false on error; - */ -{ - return fexpandsym(source, target, (RILE*)0); -} - - int -fexpandsym(source, target, fp) - char const *source; - struct buf *target; - RILE *fp; -/* Same as expandsym, except if FP is nonzero, it is used to expand KDELIM. */ -{ - register char const *sp, *bp; - register char *tp; - char const *tlim; - int dots; - - sp = source; - bufalloc(target, 1); - tp = target->string; - if (!sp || !*sp) { /* Accept 0 pointer as a legal value. */ - *tp='\0'; - return true; - } - if (sp[0] == KDELIM && !sp[1]) { - if (!getoldkeys(fp)) - return false; - if (!*prevrev.string) { - workerror("working file lacks revision number"); - return false; - } - bufscpy(target, prevrev.string); - return true; - } - tlim = tp + target->size; - dots = 0; - - for (;;) { - register char *p = tp; - size_t s = tp - target->string; - int id = false; - for (;;) { - switch (ctab[(unsigned char)*sp]) { - case IDCHAR: - case LETTER: - case Letter: - id = true; - /* fall into */ - case DIGIT: - if (tlim <= p) - p = bufenlarge(target, &tlim); - *p++ = *sp++; - continue; - - default: - break; - } - break; - } - if (tlim <= p) - p = bufenlarge(target, &tlim); - *p = 0; - tp = target->string + s; - - if (id) { - bp = lookupsym(tp); - if (!bp) { - rcserror("Symbolic name `%s' is undefined.",tp); - return false; - } - } else { - /* skip leading zeros */ - for (bp = tp; *bp=='0' && isdigit(bp[1]); bp++) - continue; - - if (!*bp) - if (s || *sp!='.') - break; - else { - /* Insert default branch before initial `.'. */ - char const *b; - if (Dbranch) - b = Dbranch; - else if (Head) - b = Head->num; - else - break; - getbranchno(b, target); - bp = tp = target->string; - tlim = tp + target->size; - } - } - - while ((*tp++ = *bp++)) - if (tlim <= tp) - tp = bufenlarge(target, &tlim); - - switch (*sp++) { - case '\0': - return true; - - case '.': - if (!*sp) { - if (dots & 1) - break; - if (!(bp = branchtip(target->string))) - return false; - bufscpy(target, bp); - return true; - } - ++dots; - tp[-1] = '.'; - continue; - } - break; - } - - rcserror("improper revision number: %s", source); - return false; -} - - char const * -namedrev(name, delta) - char const *name; - struct hshentry *delta; -/* Yield NAME if it names DELTA, 0 otherwise. */ -{ - if (name) { - char const *id = 0, *p, *val; - for (p = name; ; p++) - switch (ctab[(unsigned char)*p]) { - case IDCHAR: - case LETTER: - case Letter: - id = name; - break; - - case DIGIT: - break; - - case UNKN: - if (!*p && id && - (val = lookupsym(id)) && - strcmp(val, delta->num) == 0 - ) - return id; - /* fall into */ - default: - return 0; - } - } - return 0; -} - - static char const * -branchtip(branch) - char const *branch; -{ - struct hshentry *h; - struct hshentries *hs; - - h = genrevs(branch, (char*)0, (char*)0, (char*)0, &hs); - return h ? h->num : (char const*)0; -} - - char const * -tiprev() -{ - return Dbranch ? branchtip(Dbranch) : Head ? Head->num : (char const*)0; -} - - - -#ifdef REVTEST - -/* -* Test the routines that generate a sequence of delta numbers -* needed to regenerate a given delta. -*/ - -char const cmdid[] = "revtest"; - - int -main(argc,argv) -int argc; char * argv[]; -{ - static struct buf numricrevno; - char symrevno[100]; /* used for input of revision numbers */ - char author[20]; - char state[20]; - char date[20]; - struct hshentries *gendeltas; - struct hshentry * target; - int i; - - if (argc<2) { - aputs("No input file\n",stderr); - exitmain(EXIT_FAILURE); - } - if (!(finptr=Iopen(argv[1], FOPEN_R, (struct stat*)0))) { - faterror("can't open input file %s", argv[1]); - } - Lexinit(); - getadmin(); - - gettree(); - - getdesc(false); - - do { - /* all output goes to stderr, to have diagnostics and */ - /* errors in sequence. */ - aputs("\nEnter revision number or <return> or '.': ",stderr); - if (!fgets(symrevno, 100, stdin)) break; - if (*symrevno == '.') break; - aprintf(stderr,"%s;\n",symrevno); - expandsym(symrevno,&numricrevno); - aprintf(stderr,"expanded number: %s; ",numricrevno.string); - aprintf(stderr,"Date: "); - fgets(date, 20, stdin); aprintf(stderr,"%s; ",date); - aprintf(stderr,"Author: "); - fgets(author, 20, stdin); aprintf(stderr,"%s; ",author); - aprintf(stderr,"State: "); - fgets(state, 20, stdin); aprintf(stderr, "%s;\n", state); - target = genrevs(numricrevno.string, *date?date:(char *)0, *author?author:(char *)0, - *state?state:(char*)0, &gendeltas); - if (target) { - while (gendeltas) { - aprintf(stderr,"%s\n",gendeltas->first->num); - gendeltas = gendeltas->next; - } - } - } while (true); - aprintf(stderr,"done\n"); - exitmain(EXIT_SUCCESS); -} - -void exiterr() { _exit(EXIT_FAILURE); } - -#endif diff --git a/gnu/usr.bin/rcs/lib/rcssyn.c b/gnu/usr.bin/rcs/lib/rcssyn.c deleted file mode 100644 index 07f155b..0000000 --- a/gnu/usr.bin/rcs/lib/rcssyn.c +++ /dev/null @@ -1,681 +0,0 @@ -/* RCS file syntactic analysis */ - -/****************************************************************************** - * Syntax Analysis. - * Keyword table - * Testprogram: define SYNTEST - * Compatibility with Release 2: define COMPAT2=1 - ****************************************************************************** - */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.15 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.14 1995/06/01 16:23:43 eggert - * (expand_names): Add "b" for -kb. - * (getdelta): Don't strip leading "19" from MKS RCS dates; see cmpdate. - * - * Revision 5.13 1994/03/20 04:52:58 eggert - * Remove lint. - * - * Revision 5.12 1993/11/03 17:42:27 eggert - * Parse MKS RCS dates; ignore \r in diff control lines. - * Don't discard ignored phrases. Improve quality of diagnostics. - * - * Revision 5.11 1992/07/28 16:12:44 eggert - * Avoid `unsigned'. Statement macro names now end in _. - * - * Revision 5.10 1992/01/24 18:44:19 eggert - * Move put routines to rcsgen.c. - * - * Revision 5.9 1992/01/06 02:42:34 eggert - * ULONG_MAX/10 -> ULONG_MAX_OVER_10 - * while (E) ; -> while (E) continue; - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Tune. - * - * Revision 5.7 1991/04/21 11:58:29 eggert - * Disambiguate names on shortname hosts. - * Fix errno bug. Add MS-DOS support. - * - * Revision 5.6 1991/02/28 19:18:51 eggert - * Fix null termination bug in reporting keyword expansion. - * - * Revision 5.5 1991/02/25 07:12:44 eggert - * Check diff output more carefully; avoid overflow. - * - * Revision 5.4 1990/11/01 05:28:48 eggert - * When ignoring unknown phrases, copy them to the output RCS file. - * Permit arbitrary data in logs and comment leaders. - * Don't check for nontext on initial checkin. - * - * Revision 5.3 1990/09/20 07:58:32 eggert - * Remove the test for non-text bytes; it caused more pain than it cured. - * - * Revision 5.2 1990/09/04 08:02:30 eggert - * Parse RCS files with no revisions. - * Don't strip leading white space from diff commands. Count RCS lines better. - * - * Revision 5.1 1990/08/29 07:14:06 eggert - * Add -kkvl. Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:13:44 eggert - * Try to parse future RCS formats without barfing. - * Add -k. Don't require final newline. - * Remove compile-time limits; use malloc instead. - * Don't output branch keyword if there's no default branch, - * because RCS version 3 doesn't understand it. - * Tune. Remove lint. - * Add support for ISO 8859. Ansify and Posixate. - * Check that a newly checked-in file is acceptable as input to 'diff'. - * Check diff's output. - * - * Revision 4.6 89/05/01 15:13:32 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.5 88/08/09 19:13:21 eggert - * Allow cc -R; remove lint. - * - * Revision 4.4 87/12/18 11:46:16 narten - * more lint cleanups (Guy Harris) - * - * Revision 4.3 87/10/18 10:39:36 narten - * Updating version numbers. Changes relative to 1.1 actually relative to - * 4.1 - * - * Revision 1.3 87/09/24 14:00:49 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:40 jenkins - * Port to suns - * - * Revision 4.1 83/03/28 11:38:49 wft - * Added parsing and printing of default branch. - * - * Revision 3.6 83/01/15 17:46:50 wft - * Changed readdelta() to initialize selector and log-pointer. - * Changed puttree to check for selector==DELETE; putdtext() uses DELNUMFORM. - * - * Revision 3.5 82/12/08 21:58:58 wft - * renamed Commentleader to Commleader. - * - * Revision 3.4 82/12/04 13:24:40 wft - * Added routine gettree(), which updates keeplock after reading the - * delta tree. - * - * Revision 3.3 82/11/28 21:30:11 wft - * Reading and printing of Suffix removed; version COMPAT2 skips the - * Suffix for files of release 2 format. Fixed problems with printing nil. - * - * Revision 3.2 82/10/18 21:18:25 wft - * renamed putdeltatext to putdtext. - * - * Revision 3.1 82/10/11 19:45:11 wft - * made sure getc() returns into an integer. - */ - - - -/* version COMPAT2 reads files of the format of release 2 and 3, but - * generates files of release 3 format. Need not be defined if no - * old RCS files generated with release 2 exist. - */ - -#include "rcsbase.h" - -libId(synId, "$FreeBSD$") - -static char const *getkeyval P((char const*,enum tokens,int)); -static int getdelta P((void)); -static int strn2expmode P((char const*,size_t)); -static struct hshentry *getdnum P((void)); -static void badDiffOutput P((char const*)) exiting; -static void diffLineNumberTooLarge P((char const*)) exiting; -static void getsemi P((char const*)); - -/* keyword table */ - -char const - Kaccess[] = "access", - Kauthor[] = "author", - Kbranch[] = "branch", - Kcomment[] = "comment", - Kdate[] = "date", - Kdesc[] = "desc", - Kexpand[] = "expand", - Khead[] = "head", - Klocks[] = "locks", - Klog[] = "log", - Knext[] = "next", - Kstate[] = "state", - Kstrict[] = "strict", - Ksymbols[] = "symbols", - Ktext[] = "text"; - -static char const -#if COMPAT2 - Ksuffix[] = "suffix", -#endif - K_branches[]= "branches"; - -static struct buf Commleader; -struct cbuf Comment; -struct cbuf Ignored; -struct access * AccessList; -struct assoc * Symbols; -struct rcslock *Locks; -int Expand; -int StrictLocks; -struct hshentry * Head; -char const * Dbranch; -int TotalDeltas; - - - static void -getsemi(key) - char const *key; -/* Get a semicolon to finish off a phrase started by KEY. */ -{ - if (!getlex(SEMI)) - fatserror("missing ';' after '%s'", key); -} - - static struct hshentry * -getdnum() -/* Get a delta number. */ -{ - register struct hshentry *delta = getnum(); - if (delta && countnumflds(delta->num)&1) - fatserror("%s isn't a delta number", delta->num); - return delta; -} - - - void -getadmin() -/* Read an <admin> and initialize the appropriate global variables. */ -{ - register char const *id; - struct access * newaccess; - struct assoc * newassoc; - struct rcslock *newlock; - struct hshentry * delta; - struct access **LastAccess; - struct assoc **LastSymbol; - struct rcslock **LastLock; - struct buf b; - struct cbuf cb; - - TotalDeltas=0; - - getkey(Khead); - Head = getdnum(); - getsemi(Khead); - - Dbranch = 0; - if (getkeyopt(Kbranch)) { - if ((delta = getnum())) - Dbranch = delta->num; - getsemi(Kbranch); - } - - -#if COMPAT2 - /* read suffix. Only in release 2 format */ - if (getkeyopt(Ksuffix)) { - if (nexttok==STRING) { - readstring(); nextlex(); /* Throw away the suffix. */ - } else if (nexttok==ID) { - nextlex(); - } - getsemi(Ksuffix); - } -#endif - - getkey(Kaccess); - LastAccess = &AccessList; - while ((id = getid())) { - newaccess = ftalloc(struct access); - newaccess->login = id; - *LastAccess = newaccess; - LastAccess = &newaccess->nextaccess; - } - *LastAccess = 0; - getsemi(Kaccess); - - getkey(Ksymbols); - LastSymbol = &Symbols; - while ((id = getid())) { - if (!getlex(COLON)) - fatserror("missing ':' in symbolic name definition"); - if (!(delta=getnum())) { - fatserror("missing number in symbolic name definition"); - } else { /*add new pair to association list*/ - newassoc = ftalloc(struct assoc); - newassoc->symbol=id; - newassoc->num = delta->num; - *LastSymbol = newassoc; - LastSymbol = &newassoc->nextassoc; - } - } - *LastSymbol = 0; - getsemi(Ksymbols); - - getkey(Klocks); - LastLock = &Locks; - while ((id = getid())) { - if (!getlex(COLON)) - fatserror("missing ':' in lock"); - if (!(delta=getdnum())) { - fatserror("missing number in lock"); - } else { /*add new pair to lock list*/ - newlock = ftalloc(struct rcslock); - newlock->login=id; - newlock->delta=delta; - *LastLock = newlock; - LastLock = &newlock->nextlock; - } - } - *LastLock = 0; - getsemi(Klocks); - - if ((StrictLocks = getkeyopt(Kstrict))) - getsemi(Kstrict); - - clear_buf(&Comment); - if (getkeyopt(Kcomment)) { - if (nexttok==STRING) { - Comment = savestring(&Commleader); - nextlex(); - } - getsemi(Kcomment); - } - - Expand = KEYVAL_EXPAND; - if (getkeyopt(Kexpand)) { - if (nexttok==STRING) { - bufautobegin(&b); - cb = savestring(&b); - if ((Expand = strn2expmode(cb.string,cb.size)) < 0) - fatserror("unknown expand mode %.*s", - (int)cb.size, cb.string - ); - bufautoend(&b); - nextlex(); - } - getsemi(Kexpand); - } - Ignored = getphrases(Kdesc); -} - -char const *const expand_names[] = { - /* These must agree with *_EXPAND in rcsbase.h. */ - "kv", "kvl", "k", "v", "o", "b", - 0 -}; - - int -str2expmode(s) - char const *s; -/* Yield expand mode corresponding to S, or -1 if bad. */ -{ - return strn2expmode(s, strlen(s)); -} - - static int -strn2expmode(s, n) - char const *s; - size_t n; -{ - char const *const *p; - - for (p = expand_names; *p; ++p) - if (memcmp(*p,s,n) == 0 && !(*p)[n]) - return p - expand_names; - return -1; -} - - - void -ignorephrases(key) - const char *key; -/* -* Ignore a series of phrases that do not start with KEY. -* Stop when the next phrase starts with a token that is not an identifier, -* or is KEY. -*/ -{ - for (;;) { - nextlex(); - if (nexttok != ID || strcmp(NextString,key) == 0) - break; - warnignore(); - hshenter=false; - for (;; nextlex()) { - switch (nexttok) { - case SEMI: hshenter=true; break; - case ID: - case NUM: ffree1(NextString); continue; - case STRING: readstring(); continue; - default: continue; - } - break; - } - } -} - - - static int -getdelta() -/* Function: reads a delta block. - * returns false if the current block does not start with a number. - */ -{ - register struct hshentry * Delta, * num; - struct branchhead **LastBranch, *NewBranch; - - if (!(Delta = getdnum())) - return false; - - hshenter = false; /*Don't enter dates into hashtable*/ - Delta->date = getkeyval(Kdate, NUM, false); - hshenter=true; /*reset hshenter for revision numbers.*/ - - Delta->author = getkeyval(Kauthor, ID, false); - - Delta->state = getkeyval(Kstate, ID, true); - - getkey(K_branches); - LastBranch = &Delta->branches; - while ((num = getdnum())) { - NewBranch = ftalloc(struct branchhead); - NewBranch->hsh = num; - *LastBranch = NewBranch; - LastBranch = &NewBranch->nextbranch; - } - *LastBranch = 0; - getsemi(K_branches); - - getkey(Knext); - Delta->next = num = getdnum(); - getsemi(Knext); - Delta->lockedby = 0; - Delta->log.string = 0; - Delta->selector = true; - Delta->ig = getphrases(Kdesc); - TotalDeltas++; - return (true); -} - - - void -gettree() -/* Function: Reads in the delta tree with getdelta(), then - * updates the lockedby fields. - */ -{ - struct rcslock const *currlock; - - while (getdelta()) - continue; - currlock=Locks; - while (currlock) { - currlock->delta->lockedby = currlock->login; - currlock = currlock->nextlock; - } -} - - - void -getdesc(prdesc) -int prdesc; -/* Function: read in descriptive text - * nexttok is not advanced afterwards. - * If prdesc is set, the text is printed to stdout. - */ -{ - - getkeystring(Kdesc); - if (prdesc) - printstring(); /*echo string*/ - else readstring(); /*skip string*/ -} - - - - - - - static char const * -getkeyval(keyword, token, optional) - char const *keyword; - enum tokens token; - int optional; -/* reads a pair of the form - * <keyword> <token> ; - * where token is one of <id> or <num>. optional indicates whether - * <token> is optional. A pointer to - * the actual character string of <id> or <num> is returned. - */ -{ - register char const *val = 0; - - getkey(keyword); - if (nexttok==token) { - val = NextString; - nextlex(); - } else { - if (!optional) - fatserror("missing %s", keyword); - } - getsemi(keyword); - return(val); -} - - - void -unexpected_EOF() -{ - rcsfaterror("unexpected EOF in diff output"); -} - - void -initdiffcmd(dc) - register struct diffcmd *dc; -/* Initialize *dc suitably for getdiffcmd(). */ -{ - dc->adprev = 0; - dc->dafter = 0; -} - - static void -badDiffOutput(buf) - char const *buf; -{ - rcsfaterror("bad diff output line: %s", buf); -} - - static void -diffLineNumberTooLarge(buf) - char const *buf; -{ - rcsfaterror("diff line number too large: %s", buf); -} - - int -getdiffcmd(finfile, delimiter, foutfile, dc) - RILE *finfile; - FILE *foutfile; - int delimiter; - struct diffcmd *dc; -/* Get a editing command output by 'diff -n' from fin. - * The input is delimited by SDELIM if delimiter is set, EOF otherwise. - * Copy a clean version of the command to fout (if nonnull). - * Yield 0 for 'd', 1 for 'a', and -1 for EOF. - * Store the command's line number and length into dc->line1 and dc->nlines. - * Keep dc->adprev and dc->dafter up to date. - */ -{ - register int c; - declarecache; - register FILE *fout; - register char *p; - register RILE *fin; - long line1, nlines, t; - char buf[BUFSIZ]; - - fin = finfile; - fout = foutfile; - setupcache(fin); cache(fin); - cachegeteof_(c, { if (delimiter) unexpected_EOF(); return -1; } ) - if (delimiter) { - if (c==SDELIM) { - cacheget_(c) - if (c==SDELIM) { - buf[0] = c; - buf[1] = 0; - badDiffOutput(buf); - } - uncache(fin); - nextc = c; - if (fout) - aprintf(fout, "%c%c", SDELIM, c); - return -1; - } - } - p = buf; - do { - if (buf+BUFSIZ-2 <= p) { - rcsfaterror("diff output command line too long"); - } - *p++ = c; - cachegeteof_(c, unexpected_EOF();) - } while (c != '\n'); - uncache(fin); - if (delimiter) - ++rcsline; - *p = '\0'; - for (p = buf+1; (c = *p++) == ' '; ) - continue; - line1 = 0; - while (isdigit(c)) { - if ( - LONG_MAX/10 < line1 || - (t = line1 * 10, (line1 = t + (c - '0')) < t) - ) - diffLineNumberTooLarge(buf); - c = *p++; - } - while (c == ' ') - c = *p++; - nlines = 0; - while (isdigit(c)) { - if ( - LONG_MAX/10 < nlines || - (t = nlines * 10, (nlines = t + (c - '0')) < t) - ) - diffLineNumberTooLarge(buf); - c = *p++; - } - if (c == '\r') - c = *p++; - if (c || !nlines) { - badDiffOutput(buf); - } - if (line1+nlines < line1) - diffLineNumberTooLarge(buf); - switch (buf[0]) { - case 'a': - if (line1 < dc->adprev) { - rcsfaterror("backward insertion in diff output: %s", buf); - } - dc->adprev = line1 + 1; - break; - case 'd': - if (line1 < dc->adprev || line1 < dc->dafter) { - rcsfaterror("backward deletion in diff output: %s", buf); - } - dc->adprev = line1; - dc->dafter = line1 + nlines; - break; - default: - badDiffOutput(buf); - } - if (fout) { - aprintf(fout, "%s\n", buf); - } - dc->line1 = line1; - dc->nlines = nlines; - return buf[0] == 'a'; -} - - - -#ifdef SYNTEST - -/* Input an RCS file and print its internal data structures. */ - -char const cmdid[] = "syntest"; - - int -main(argc,argv) -int argc; char * argv[]; -{ - - if (argc<2) { - aputs("No input file\n",stderr); - exitmain(EXIT_FAILURE); - } - if (!(finptr = Iopen(argv[1], FOPEN_R, (struct stat*)0))) { - faterror("can't open input file %s", argv[1]); - } - Lexinit(); - getadmin(); - fdlock = STDOUT_FILENO; - putadmin(); - - gettree(); - - getdesc(true); - - nextlex(); - - if (!eoflex()) { - fatserror("expecting EOF"); - } - exitmain(EXIT_SUCCESS); -} - -void exiterr() { _exit(EXIT_FAILURE); } - -#endif diff --git a/gnu/usr.bin/rcs/lib/rcstime.c b/gnu/usr.bin/rcs/lib/rcstime.c deleted file mode 100644 index cfd4660..0000000 --- a/gnu/usr.bin/rcs/lib/rcstime.c +++ /dev/null @@ -1,191 +0,0 @@ -/* Convert between RCS time format and Posix and/or C formats. */ - -/* Copyright 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#include "rcsbase.h" -#include "partime.h" -#include "maketime.h" - -libId(rcstimeId, "$FreeBSD$") - -static long zone_offset; /* seconds east of UTC, or TM_LOCAL_ZONE */ -static int use_zone_offset; /* if zero, use UTC without zone indication */ - -/* -* Convert Unix time to RCS format. -* For compatibility with older versions of RCS, -* dates from 1900 through 1999 are stored without the leading "19". -*/ - void -time2date(unixtime,date) - time_t unixtime; - char date[datesize]; -{ - register struct tm const *tm = time2tm(unixtime, RCSversion<VERSION(5)); - VOID sprintf(date, -# if has_printf_dot - "%.2d.%.2d.%.2d.%.2d.%.2d.%.2d", -# else - "%02d.%02d.%02d.%02d.%02d.%02d", -# endif - tm->tm_year + ((unsigned)tm->tm_year < 100 ? 0 : 1900), - tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec - ); -} - -/* Like str2time, except die if an error was found. */ -static time_t str2time_checked P((char const*,time_t,long)); - static time_t -str2time_checked(source, default_time, default_zone) - char const *source; - time_t default_time; - long default_zone; -{ - time_t t = str2time(source, default_time, default_zone); - if (t == -1) - faterror("unknown date/time: %s", source); - return t; -} - -/* -* Parse a free-format date in SOURCE, convert it -* into RCS internal format, and store the result into TARGET. -*/ - void -str2date(source, target) - char const *source; - char target[datesize]; -{ - time2date( - str2time_checked(source, now(), - use_zone_offset ? zone_offset - : RCSversion<VERSION(5) ? TM_LOCAL_ZONE - : 0 - ), - target - ); -} - -/* Convert an RCS internal format date to time_t. */ - time_t -date2time(source) - char const source[datesize]; -{ - char s[datesize + zonelenmax]; - return str2time_checked(date2str(source, s), (time_t)0, 0); -} - - -/* Set the time zone for date2str output. */ - void -zone_set(s) - char const *s; -{ - if ((use_zone_offset = *s)) { - long zone; - char const *zonetail = parzone(s, &zone); - if (!zonetail || *zonetail) - error("%s: not a known time zone", s); - else - zone_offset = zone; - } -} - - -/* -* Format a user-readable form of the RCS format DATE into the buffer DATEBUF. -* Yield DATEBUF. -*/ - char const * -date2str(date, datebuf) - char const date[datesize]; - char datebuf[datesize + zonelenmax]; -{ - register char const *p = date; - - while (*p++ != '.') - continue; - if (!use_zone_offset) - VOID sprintf(datebuf, - "19%.*s/%.2s/%.2s %.2s:%.2s:%s" - + (date[2]=='.' && VERSION(5)<=RCSversion ? 0 : 2), - (int)(p-date-1), date, - p, p+3, p+6, p+9, p+12 - ); - else { - struct tm t; - struct tm const *z; - int non_hour; - long zone; - char c; - - t.tm_year = atoi(date) - (date[2]=='.' ? 0 : 1900); - t.tm_mon = atoi(p) - 1; - t.tm_mday = atoi(p+3); - t.tm_hour = atoi(p+6); - t.tm_min = atoi(p+9); - t.tm_sec = atoi(p+12); - t.tm_wday = -1; - zone = zone_offset; - if (zone == TM_LOCAL_ZONE) { - time_t u = tm2time(&t, 0), d; - z = localtime(&u); - d = difftm(z, &t); - zone = (time_t)-1 < 0 || d < -d ? d : -(long)-d; - } else { - adjzone(&t, zone); - z = &t; - } - c = '+'; - if (zone < 0) { - zone = -zone; - c = '-'; - } - VOID sprintf(datebuf, -# if has_printf_dot - "%.2d-%.2d-%.2d %.2d:%.2d:%.2d%c%.2d", -# else - "%02d-%02d-%02d %02d:%02d:%02d%c%02d", -# endif - z->tm_year + 1900, - z->tm_mon + 1, z->tm_mday, z->tm_hour, z->tm_min, z->tm_sec, - c, (int) (zone / (60*60)) - ); - if ((non_hour = zone % (60*60))) { -# if has_printf_dot - static char const fmt[] = ":%.2d"; -# else - static char const fmt[] = ":%02d"; -# endif - VOID sprintf(datebuf + strlen(datebuf), fmt, non_hour / 60); - if ((non_hour %= 60)) - VOID sprintf(datebuf + strlen(datebuf), fmt, non_hour); - } - } - return datebuf; -} diff --git a/gnu/usr.bin/rcs/lib/rcsutil.c b/gnu/usr.bin/rcs/lib/rcsutil.c deleted file mode 100644 index e10afff..0000000 --- a/gnu/usr.bin/rcs/lib/rcsutil.c +++ /dev/null @@ -1,1398 +0,0 @@ -/* RCS utility functions */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS 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. - -RCS 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 RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - - - - -/* - * Revision 5.20 1995/06/16 06:19:24 eggert - * (catchsig): Remove `return'. - * Update FSF address. - * - * Revision 5.19 1995/06/02 18:19:00 eggert - * (catchsigaction): New name for `catchsig', for sa_sigaction signature. - * Use nRCS even if !has_psiginfo, to remove unused variable warning. - * (setup_catchsig): Use sa_sigaction only if has_sa_sigaction. - * Use ENOTSUP only if defined. - * - * Revision 5.18 1995/06/01 16:23:43 eggert - * (catchsig, restoreints, setup_catchsig): Use SA_SIGINFO, not has_psiginfo, - * to determine whether to use SA_SIGINFO feature, - * but also check at runtime whether the feature works. - * (catchsig): If an mmap_signal occurs, report the affected file name. - * (unsupported_SA_SIGINFO, accessName): New variables. - * (setup_catchsig): If using SA_SIGINFO, use sa_sigaction, not sa_handler. - * If SA_SIGINFO fails, fall back on sa_handler method. - * - * (readAccessFilenameBuffer, dupSafer, fdSafer, fopenSafer): New functions. - * (concatenate): Remove. - * - * (runv): Work around bad_wait_if_SIGCHLD_ignored bug. - * Remove reference to OPEN_O_WORK. - * - * Revision 5.17 1994/03/20 04:52:58 eggert - * Specify subprocess input via file descriptor, not file name. - * Avoid messing with I/O buffers in the child process. - * Define dup in terms of F_DUPFD if it exists. - * Move setmtime to rcsedit.c. Remove lint. - * - * Revision 5.16 1993/11/09 17:40:15 eggert - * -V now prints version on stdout and exits. - * - * Revision 5.15 1993/11/03 17:42:27 eggert - * Use psiginfo and setreuid if available. Move date2str to maketime.c. - * - * Revision 5.14 1992/07/28 16:12:44 eggert - * Add -V. has_sigaction overrides sig_zaps_handler. Fix -M bug. - * Add mmap_signal, which minimizes signal handling for non-mmap hosts. - * - * Revision 5.13 1992/02/17 23:02:28 eggert - * Work around NFS mmap SIGBUS problem. Add -T support. - * - * Revision 5.12 1992/01/24 18:44:19 eggert - * Work around NFS mmap bug that leads to SIGBUS core dumps. lint -> RCS_lint - * - * Revision 5.11 1992/01/06 02:42:34 eggert - * O_BINARY -> OPEN_O_WORK - * while (E) ; -> while (E) continue; - * - * Revision 5.10 1991/10/07 17:32:46 eggert - * Support piece tables even if !has_mmap. - * - * Revision 5.9 1991/08/19 03:13:55 eggert - * Add spawn() support. Explicate assumptions about getting invoker's name. - * Standardize user-visible dates. Tune. - * - * Revision 5.8 1991/04/21 11:58:30 eggert - * Plug setuid security hole. - * - * Revision 5.6 1991/02/26 17:48:39 eggert - * Fix setuid bug. Use fread, fwrite more portably. - * Support waitpid. Don't assume -1 is acceptable to W* macros. - * strsave -> str_save (DG/UX name clash) - * - * Revision 5.5 1990/12/04 05:18:49 eggert - * Don't output a blank line after a signal diagnostic. - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.4 1990/11/01 05:03:53 eggert - * Remove unneeded setid check. Add awrite(), fremember(). - * - * Revision 5.3 1990/10/06 00:16:45 eggert - * Don't fread F if feof(F). - * - * Revision 5.2 1990/09/04 08:02:31 eggert - * Store fread()'s result in an fread_type object. - * - * Revision 5.1 1990/08/29 07:14:07 eggert - * Declare getpwuid() more carefully. - * - * Revision 5.0 1990/08/22 08:13:46 eggert - * Add setuid support. Permit multiple locks per user. - * Remove compile-time limits; use malloc instead. - * Switch to GMT. Permit dates past 1999/12/31. - * Add -V. Remove snooping. Ansify and Posixate. - * Tune. Some USG hosts define NSIG but not sys_siglist. - * Don't run /bin/sh if it's hopeless. - * Don't leave garbage behind if the output is an empty pipe. - * Clean up after SIGXCPU or SIGXFSZ. Print name of signal that caused cleanup. - * - * Revision 4.6 89/05/01 15:13:40 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.5 88/11/08 16:01:02 narten - * corrected use of varargs routines - * - * Revision 4.4 88/08/09 19:13:24 eggert - * Check for memory exhaustion. - * Permit signal handlers to yield either 'void' or 'int'; fix oldSIGINT botch. - * Use execv(), not system(); yield exit status like diff(1)'s. - * - * Revision 4.3 87/10/18 10:40:22 narten - * Updating version numbers. Changes relative to 1.1 actually - * relative to 4.1 - * - * Revision 1.3 87/09/24 14:01:01 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:43 jenkins - * Port to suns - * - * Revision 4.1 83/05/10 15:53:13 wft - * Added getcaller() and findlock(). - * Changed catchints() to check SIGINT for SIG_IGN before setting up the signal - * (needed for background jobs in older shells). Added restoreints(). - * Removed printing of full RCS path from logcommand(). - * - * Revision 3.8 83/02/15 15:41:49 wft - * Added routine fastcopy() to copy remainder of a file in blocks. - * - * Revision 3.7 82/12/24 15:25:19 wft - * added catchints(), ignoreints() for catching and ingnoring interrupts; - * fixed catchsig(). - * - * Revision 3.6 82/12/08 21:52:05 wft - * Using DATEFORM to format dates. - * - * Revision 3.5 82/12/04 18:20:49 wft - * Replaced SNOOPDIR with SNOOPFILE; changed addlock() to update - * lockedby-field. - * - * Revision 3.4 82/12/03 17:17:43 wft - * Added check to addlock() ensuring only one lock per person. - * Addlock also returns a pointer to the lock created. Deleted fancydate(). - * - * Revision 3.3 82/11/27 12:24:37 wft - * moved rmsema(), trysema(), trydiraccess(), getfullRCSname() to rcsfnms.c. - * Introduced macro SNOOP so that snoop can be placed in directory other than - * TARGETDIR. Changed %02d to %.2d for compatibility reasons. - * - * Revision 3.2 82/10/18 21:15:11 wft - * added function getfullRCSname(). - * - * Revision 3.1 82/10/13 16:17:37 wft - * Cleanup message is now suppressed in quiet mode. - */ - - - - -#include "rcsbase.h" - -libId(utilId, "$FreeBSD$") - -#if !has_memcmp - int -memcmp(s1, s2, n) - void const *s1, *s2; - size_t n; -{ - register unsigned char const - *p1 = (unsigned char const*)s1, - *p2 = (unsigned char const*)s2; - register size_t i = n; - register int r = 0; - while (i-- && !(r = (*p1++ - *p2++))) - ; - return r; -} -#endif - -#if !has_memcpy - void * -memcpy(s1, s2, n) - void *s1; - void const *s2; - size_t n; -{ - register char *p1 = (char*)s1; - register char const *p2 = (char const*)s2; - while (n--) - *p1++ = *p2++; - return s1; -} -#endif - -#if RCS_lint - malloc_type lintalloc; -#endif - -/* - * list of blocks allocated with ftestalloc() - * These blocks can be freed by ffree when we're done with the current file. - * We could put the free block inside struct alloclist, rather than a pointer - * to the free block, but that would be less portable. - */ -struct alloclist { - malloc_type alloc; - struct alloclist *nextalloc; -}; -static struct alloclist *alloced; - - - static malloc_type okalloc P((malloc_type)); - static malloc_type -okalloc(p) - malloc_type p; -{ - if (!p) - faterror("out of memory"); - return p; -} - - malloc_type -testalloc(size) - size_t size; -/* Allocate a block, testing that the allocation succeeded. */ -{ - return okalloc(malloc(size)); -} - - malloc_type -testrealloc(ptr, size) - malloc_type ptr; - size_t size; -/* Reallocate a block, testing that the allocation succeeded. */ -{ - return okalloc(realloc(ptr, size)); -} - - malloc_type -fremember(ptr) - malloc_type ptr; -/* Remember PTR in 'alloced' so that it can be freed later. Yield PTR. */ -{ - register struct alloclist *q = talloc(struct alloclist); - q->nextalloc = alloced; - alloced = q; - return q->alloc = ptr; -} - - malloc_type -ftestalloc(size) - size_t size; -/* Allocate a block, putting it in 'alloced' so it can be freed later. */ -{ - return fremember(testalloc(size)); -} - - void -ffree() -/* Free all blocks allocated with ftestalloc(). */ -{ - register struct alloclist *p, *q; - for (p = alloced; p; p = q) { - q = p->nextalloc; - tfree(p->alloc); - tfree(p); - } - alloced = 0; -} - - void -ffree1(f) - register char const *f; -/* Free the block f, which was allocated by ftestalloc. */ -{ - register struct alloclist *p, **a = &alloced; - - while ((p = *a)->alloc != f) - a = &p->nextalloc; - *a = p->nextalloc; - tfree(p->alloc); - tfree(p); -} - - char * -str_save(s) - char const *s; -/* Save s in permanently allocated storage. */ -{ - return strcpy(tnalloc(char, strlen(s)+1), s); -} - - char * -fstr_save(s) - char const *s; -/* Save s in storage that will be deallocated when we're done with this file. */ -{ - return strcpy(ftnalloc(char, strlen(s)+1), s); -} - - char * -cgetenv(name) - char const *name; -/* Like getenv(), but yield a copy; getenv() can overwrite old results. */ -{ - register char *p; - - return (p=getenv(name)) ? str_save(p) : p; -} - - char const * -getusername(suspicious) - int suspicious; -/* Get the caller's login name. Trust only getwpuid if SUSPICIOUS. */ -{ - static char *name; - - if (!name) { - if ( - /* Prefer getenv() unless suspicious; it's much faster. */ -# if getlogin_is_secure - (suspicious - || ( - !(name = cgetenv("LOGNAME")) - && !(name = cgetenv("USER")) - )) - && !(name = getlogin()) -# else - suspicious - || ( - !(name = cgetenv("LOGNAME")) - && !(name = cgetenv("USER")) - && !(name = getlogin()) - ) -# endif - ) { -#if has_getuid && has_getpwuid - struct passwd const *pw = getpwuid(ruid()); - if (!pw) - faterror("no password entry for userid %lu", - (unsigned long)ruid() - ); - name = pw->pw_name; -#else -#if has_setuid - faterror("setuid not supported"); -#else - faterror("Who are you? Please setenv LOGNAME."); -#endif -#endif - } - checksid(name); - } - return name; -} - - - - -#if has_signal - -/* - * Signal handling - * - * Standard C places too many restrictions on signal handlers. - * We obey as many of them as we can. - * Posix places fewer restrictions, and we are Posix-compatible here. - */ - -static sig_atomic_t volatile heldsignal, holdlevel; -#ifdef SA_SIGINFO - static int unsupported_SA_SIGINFO; - static siginfo_t bufsiginfo; - static siginfo_t *volatile heldsiginfo; -#endif - - -#if has_NFS && has_mmap && large_memory && mmap_signal - static char const *accessName; - - void - readAccessFilenameBuffer(filename, p) - char const *filename; - unsigned char const *p; - { - unsigned char volatile t; - accessName = filename; - t = *p; - accessName = 0; - } -#else -# define accessName ((char const *) 0) -#endif - - -#if !has_psignal - -# define psignal my_psignal - static void my_psignal P((int,char const*)); - static void -my_psignal(sig, s) - int sig; - char const *s; -{ - char const *sname = "Unknown signal"; -# if has_sys_siglist && defined(NSIG) - if ((unsigned)sig < NSIG) - sname = sys_siglist[sig]; -# else - switch (sig) { -# ifdef SIGHUP - case SIGHUP: sname = "Hangup"; break; -# endif -# ifdef SIGINT - case SIGINT: sname = "Interrupt"; break; -# endif -# ifdef SIGPIPE - case SIGPIPE: sname = "Broken pipe"; break; -# endif -# ifdef SIGQUIT - case SIGQUIT: sname = "Quit"; break; -# endif -# ifdef SIGTERM - case SIGTERM: sname = "Terminated"; break; -# endif -# ifdef SIGXCPU - case SIGXCPU: sname = "Cputime limit exceeded"; break; -# endif -# ifdef SIGXFSZ - case SIGXFSZ: sname = "Filesize limit exceeded"; break; -# endif -# if has_mmap && large_memory -# if defined(SIGBUS) && mmap_signal==SIGBUS - case SIGBUS: sname = "Bus error"; break; -# endif -# if defined(SIGSEGV) && mmap_signal==SIGSEGV - case SIGSEGV: sname = "Segmentation fault"; break; -# endif -# endif - } -# endif - - /* Avoid calling sprintf etc., in case they're not reentrant. */ - { - char const *p; - char buf[BUFSIZ], *b = buf; - for (p = s; *p; *b++ = *p++) - continue; - *b++ = ':'; - *b++ = ' '; - for (p = sname; *p; *b++ = *p++) - continue; - *b++ = '\n'; - VOID write(STDERR_FILENO, buf, b - buf); - } -} -#endif - -static signal_type catchsig P((int)); -#ifdef SA_SIGINFO - static signal_type catchsigaction P((int,siginfo_t*,void*)); -#endif - - static signal_type -catchsig(s) - int s; -#ifdef SA_SIGINFO -{ - catchsigaction(s, (siginfo_t *)0, (void *)0); -} - static signal_type -catchsigaction(s, i, c) - int s; - siginfo_t *i; - void *c; -#endif -{ -# if sig_zaps_handler - /* If a signal arrives before we reset the handler, we lose. */ - VOID signal(s, SIG_IGN); -# endif - -# ifdef SA_SIGINFO - if (!unsupported_SA_SIGINFO) - i = 0; -# endif - - if (holdlevel) { - heldsignal = s; -# ifdef SA_SIGINFO - if (i) { - bufsiginfo = *i; - heldsiginfo = &bufsiginfo; - } -# endif - return; - } - - ignoreints(); - setrid(); - if (!quietflag) { - /* Avoid calling sprintf etc., in case they're not reentrant. */ - char const *p; - char buf[BUFSIZ], *b = buf; - - if ( ! ( -# if has_mmap && large_memory && mmap_signal - /* Check whether this signal was planned. */ - s == mmap_signal && accessName -# else - 0 -# endif - )) { - char const *nRCS = "\nRCS"; -# if defined(SA_SIGINFO) && has_si_errno && has_mmap && large_memory && mmap_signal - if (s == mmap_signal && i && i->si_errno) { - errno = i->si_errno; - perror(nRCS++); - } -# endif -# if defined(SA_SIGINFO) && has_psiginfo - if (i) - psiginfo(i, nRCS); - else - psignal(s, nRCS); -# else - psignal(s, nRCS); -# endif - } - - for (p = "RCS: "; *p; *b++ = *p++) - continue; -# if has_mmap && large_memory && mmap_signal - if (s == mmap_signal) { - p = accessName; - if (!p) - p = "Was a file changed by some other process? "; - else { - char const *p1; - for (p1 = p; *p1; p1++) - continue; - VOID write(STDERR_FILENO, buf, b - buf); - VOID write(STDERR_FILENO, p, p1 - p); - b = buf; - p = ": Permission denied. "; - } - while (*p) - *b++ = *p++; - } -# endif - for (p = "Cleaning up.\n"; *p; *b++ = *p++) - continue; - VOID write(STDERR_FILENO, buf, b - buf); - } - exiterr(); -} - - void -ignoreints() -{ - ++holdlevel; -} - - void -restoreints() -{ - if (!--holdlevel && heldsignal) -# ifdef SA_SIGINFO - VOID catchsigaction(heldsignal, heldsiginfo, (void *)0); -# else - VOID catchsig(heldsignal); -# endif -} - - -static void setup_catchsig P((int const*,int)); - -#if has_sigaction - - static void check_sig P((int)); - static void - check_sig(r) - int r; - { - if (r != 0) - efaterror("signal handling"); - } - - static void - setup_catchsig(sig, sigs) - int const *sig; - int sigs; - { - register int i, j; - struct sigaction act; - - for (i=sigs; 0<=--i; ) { - check_sig(sigaction(sig[i], (struct sigaction*)0, &act)); - if (act.sa_handler != SIG_IGN) { - act.sa_handler = catchsig; -# ifdef SA_SIGINFO - if (!unsupported_SA_SIGINFO) { -# if has_sa_sigaction - act.sa_sigaction = catchsigaction; -# else - act.sa_handler = catchsigaction; -# endif - act.sa_flags |= SA_SIGINFO; - } -# endif - for (j=sigs; 0<=--j; ) - check_sig(sigaddset(&act.sa_mask, sig[j])); - if (sigaction(sig[i], &act, (struct sigaction*)0) != 0) { -# if defined(SA_SIGINFO) && defined(ENOTSUP) - if (errno == ENOTSUP && !unsupported_SA_SIGINFO) { - /* Turn off use of SA_SIGINFO and try again. */ - unsupported_SA_SIGINFO = 1; - i++; - continue; - } -# endif - check_sig(-1); - } - } - } - } - -#else -#if has_sigblock - - static void - setup_catchsig(sig, sigs) - int const *sig; - int sigs; - { - register int i; - int mask; - - mask = 0; - for (i=sigs; 0<=--i; ) - mask |= sigmask(sig[i]); - mask = sigblock(mask); - for (i=sigs; 0<=--i; ) - if ( - signal(sig[i], catchsig) == SIG_IGN && - signal(sig[i], SIG_IGN) != catchsig - ) - faterror("signal catcher failure"); - VOID sigsetmask(mask); - } - -#else - - static void - setup_catchsig(sig, sigs) - int const *sig; - int sigs; - { - register i; - - for (i=sigs; 0<=--i; ) - if ( - signal(sig[i], SIG_IGN) != SIG_IGN && - signal(sig[i], catchsig) != SIG_IGN - ) - faterror("signal catcher failure"); - } - -#endif -#endif - - -static int const regsigs[] = { -# ifdef SIGHUP - SIGHUP, -# endif -# ifdef SIGINT - SIGINT, -# endif -# ifdef SIGPIPE - SIGPIPE, -# endif -# ifdef SIGQUIT - SIGQUIT, -# endif -# ifdef SIGTERM - SIGTERM, -# endif -# ifdef SIGXCPU - SIGXCPU, -# endif -# ifdef SIGXFSZ - SIGXFSZ, -# endif -}; - - void -catchints() -{ - static int catching_ints; - if (!catching_ints) { - catching_ints = true; - setup_catchsig(regsigs, (int) (sizeof(regsigs)/sizeof(*regsigs))); - } -} - -#if has_mmap && large_memory && mmap_signal - - /* - * If you mmap an NFS file, and someone on another client removes the last - * link to that file, and you later reference an uncached part of that file, - * you'll get a SIGBUS or SIGSEGV (depending on the operating system). - * Catch the signal and report the problem to the user. - * Unfortunately, there's no portable way to differentiate between this - * problem and actual bugs in the program. - * This NFS problem is rare, thank goodness. - * - * This can also occur if someone truncates the file, even without NFS. - */ - - static int const mmapsigs[] = { mmap_signal }; - - void - catchmmapints() - { - static int catching_mmap_ints; - if (!catching_mmap_ints) { - catching_mmap_ints = true; - setup_catchsig(mmapsigs, (int)(sizeof(mmapsigs)/sizeof(*mmapsigs))); - } - } -#endif - -#endif /* has_signal */ - - - void -fastcopy(inf,outf) - register RILE *inf; - FILE *outf; -/* Function: copies the remainder of file inf to outf. - */ -{ -#if large_memory -# if maps_memory - awrite((char const*)inf->ptr, (size_t)(inf->lim - inf->ptr), outf); - inf->ptr = inf->lim; -# else - for (;;) { - awrite((char const*)inf->ptr, (size_t)(inf->readlim - inf->ptr), outf); - inf->ptr = inf->readlim; - if (inf->ptr == inf->lim) - break; - VOID Igetmore(inf); - } -# endif -#else - char buf[BUFSIZ*8]; - register fread_type rcount; - - /*now read the rest of the file in blocks*/ - while (!feof(inf)) { - if (!(rcount = Fread(buf,sizeof(*buf),sizeof(buf),inf))) { - testIerror(inf); - return; - } - awrite(buf, (size_t)rcount, outf); - } -#endif -} - -#ifndef SSIZE_MAX - /* This does not work in #ifs, but it's good enough for us. */ - /* Underestimating SSIZE_MAX may slow us down, but it won't break us. */ -# define SSIZE_MAX ((unsigned)-1 >> 1) -#endif - - void -awrite(buf, chars, f) - char const *buf; - size_t chars; - FILE *f; -{ - /* Posix 1003.1-1990 ssize_t hack */ - while (SSIZE_MAX < chars) { - if (Fwrite(buf, sizeof(*buf), SSIZE_MAX, f) != SSIZE_MAX) - Oerror(); - buf += SSIZE_MAX; - chars -= SSIZE_MAX; - } - - if (Fwrite(buf, sizeof(*buf), chars, f) != chars) - Oerror(); -} - -/* dup a file descriptor; the result must not be stdin, stdout, or stderr. */ - static int dupSafer P((int)); - static int -dupSafer(fd) - int fd; -{ -# ifdef F_DUPFD - return fcntl(fd, F_DUPFD, STDERR_FILENO + 1); -# else - int e, f, i, used = 0; - while (STDIN_FILENO <= (f = dup(fd)) && f <= STDERR_FILENO) - used |= 1<<f; - e = errno; - for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) - if (used & (1<<i)) - VOID close(i); - errno = e; - return f; -# endif -} - -/* Renumber a file descriptor so that it's not stdin, stdout, or stderr. */ - int -fdSafer(fd) - int fd; -{ - if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) { - int f = dupSafer(fd); - int e = errno; - VOID close(fd); - errno = e; - fd = f; - } - return fd; -} - -/* Like fopen, except the result is never stdin, stdout, or stderr. */ - FILE * -fopenSafer(filename, type) - char const *filename; - char const *type; -{ - FILE *stream = fopen(filename, type); - if (stream) { - int fd = fileno(stream); - if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) { - int f = dupSafer(fd); - if (f < 0) { - int e = errno; - VOID fclose(stream); - errno = e; - return 0; - } - if (fclose(stream) != 0) { - int e = errno; - VOID close(f); - errno = e; - return 0; - } - stream = fdopen(f, type); - } - } - return stream; -} - - -#ifdef F_DUPFD -# undef dup -# define dup(fd) fcntl(fd, F_DUPFD, 0) -#endif - - -#if has_fork || has_spawn - - static int movefd P((int,int)); - static int -movefd(old, new) - int old, new; -{ - if (old < 0 || old == new) - return old; -# ifdef F_DUPFD - new = fcntl(old, F_DUPFD, new); -# else - new = dup2(old, new); -# endif - return close(old)==0 ? new : -1; -} - - static int fdreopen P((int,char const*,int)); - static int -fdreopen(fd, file, flags) - int fd; - char const *file; - int flags; -{ - int newfd; - VOID close(fd); - newfd = -#if !open_can_creat - flags&O_CREAT ? creat(file, S_IRUSR|S_IWUSR) : -#endif - open(file, flags, S_IRUSR|S_IWUSR); - return movefd(newfd, fd); -} - -#if has_spawn - static void redirect P((int,int)); - static void -redirect(old, new) - int old, new; -/* -* Move file descriptor OLD to NEW. -* If OLD is -1, do nothing. -* If OLD is -2, just close NEW. -*/ -{ - if ((old != -1 && close(new) != 0) || (0 <= old && movefd(old,new) < 0)) - efaterror("spawn I/O redirection"); -} -#endif - - -#else /* !has_fork && !has_spawn */ - - static void bufargcat P((struct buf*,int,char const*)); - static void -bufargcat(b, c, s) - register struct buf *b; - int c; - register char const *s; -/* Append to B a copy of C, plus a quoted copy of S. */ -{ - register char *p; - register char const *t; - size_t bl, sl; - - for (t=s, sl=0; *t; ) - sl += 3*(*t++=='\'') + 1; - bl = strlen(b->string); - bufrealloc(b, bl + sl + 4); - p = b->string + bl; - *p++ = c; - *p++ = '\''; - while (*s) { - if (*s == '\'') { - *p++ = '\''; - *p++ = '\\'; - *p++ = '\''; - } - *p++ = *s++; - } - *p++ = '\''; - *p = 0; -} - -#endif - -#if !has_spawn && has_fork -/* -* Output the string S to stderr, without touching any I/O buffers. -* This is useful if you are a child process, whose buffers are usually wrong. -* Exit immediately if the write does not completely succeed. -*/ -static void write_stderr P((char const *)); - static void -write_stderr(s) - char const *s; -{ - size_t slen = strlen(s); - if (write(STDERR_FILENO, s, slen) != slen) - _exit(EXIT_TROUBLE); -} -#endif - -/* -* Run a command. -* infd, if not -1, is the input file descriptor. -* outname, if nonzero, is the name of the output file. -* args[1..] form the command to be run; args[0] might be modified. -*/ - int -runv(infd, outname, args) - int infd; - char const *outname, **args; -{ - int wstatus; - -#if bad_wait_if_SIGCHLD_ignored - static int fixed_SIGCHLD; - if (!fixed_SIGCHLD) { - fixed_SIGCHLD = true; -# ifndef SIGCHLD -# define SIGCHLD SIGCLD -# endif - VOID signal(SIGCHLD, SIG_DFL); - } -#endif - - oflush(); - eflush(); - { -#if has_spawn - int in, out; - char const *file; - - in = -1; - if (infd != -1 && infd != STDIN_FILENO) { - if ((in = dup(STDIN_FILENO)) < 0) { - if (errno != EBADF) - efaterror("spawn input setup"); - in = -2; - } else { -# ifdef F_DUPFD - if (close(STDIN_FILENO) != 0) - efaterror("spawn input close"); -# endif - } - if ( -# ifdef F_DUPFD - fcntl(infd, F_DUPFD, STDIN_FILENO) != STDIN_FILENO -# else - dup2(infd, STDIN_FILENO) != STDIN_FILENO -# endif - ) - efaterror("spawn input redirection"); - } - - out = -1; - if (outname) { - if ((out = dup(STDOUT_FILENO)) < 0) { - if (errno != EBADF) - efaterror("spawn output setup"); - out = -2; - } - if (fdreopen( - STDOUT_FILENO, outname, - O_CREAT | O_TRUNC | O_WRONLY - ) < 0) - efaterror(outname); - } - - wstatus = spawn_RCS(0, args[1], (char**)(args + 1)); -# ifdef RCS_SHELL - if (wstatus == -1 && errno == ENOEXEC) { - args[0] = RCS_SHELL; - wstatus = spawnv(0, args[0], (char**)args); - } -# endif - redirect(in, STDIN_FILENO); - redirect(out, STDOUT_FILENO); -#else -#if has_fork - pid_t pid; - if (!(pid = vfork())) { - char const *notfound; - if (infd != -1 && infd != STDIN_FILENO && ( -# ifdef F_DUPFD - (VOID close(STDIN_FILENO), - fcntl(infd, F_DUPFD, STDIN_FILENO) != STDIN_FILENO) -# else - dup2(infd, STDIN_FILENO) != STDIN_FILENO -# endif - )) { - /* Avoid perror since it may misuse buffers. */ - write_stderr(args[1]); - write_stderr(": I/O redirection failed\n"); - _exit(EXIT_TROUBLE); - } - - if (outname) - if (fdreopen( - STDOUT_FILENO, outname, - O_CREAT | O_TRUNC | O_WRONLY - ) < 0) { - /* Avoid perror since it may misuse buffers. */ - write_stderr(args[1]); - write_stderr(": "); - write_stderr(outname); - write_stderr(": cannot create\n"); - _exit(EXIT_TROUBLE); - } - VOID exec_RCS(args[1], (char**)(args + 1)); - notfound = args[1]; -# ifdef RCS_SHELL - if (errno == ENOEXEC) { - args[0] = notfound = RCS_SHELL; - VOID execv(args[0], (char**)args); - } -# endif - - /* Avoid perror since it may misuse buffers. */ - write_stderr(notfound); - write_stderr(": not found\n"); - _exit(EXIT_TROUBLE); - } - if (pid < 0) - efaterror("fork"); -# if has_waitpid - if (waitpid(pid, &wstatus, 0) < 0) - efaterror("waitpid"); -# else - { - pid_t w; - do { - if ((w = wait(&wstatus)) < 0) - efaterror("wait"); - } while (w != pid); - } -# endif -#else - static struct buf b; - char const *p; - - /* Use system(). On many hosts system() discards signals. Yuck! */ - p = args + 1; - bufscpy(&b, *p); - while (*++p) - bufargcat(&b, ' ', *p); - if (infd != -1 && infd != STDIN_FILENO) { - char redirection[32]; - VOID sprintf(redirection, "<&%d", infd); - bufscat(&b, redirection); - } - if (outname) - bufargcat(&b, '>', outname); - wstatus = system(b.string); -#endif -#endif - } - if (!WIFEXITED(wstatus)) { - if (WIFSIGNALED(wstatus)) { - psignal(WTERMSIG(wstatus), args[1]); - fatcleanup(1); - } - faterror("%s failed for unknown reason", args[1]); - } - return WEXITSTATUS(wstatus); -} - -#define CARGSMAX 20 -/* -* Run a command. -* infd, if not -1, is the input file descriptor. -* outname, if nonzero, is the name of the output file. -* The remaining arguments specify the command and its arguments. -*/ - int -#if has_prototypes -run(int infd, char const *outname, ...) -#else - /*VARARGS2*/ -run(infd, outname, va_alist) - int infd; - char const *outname; - va_dcl -#endif -{ - va_list ap; - char const *rgargs[CARGSMAX]; - register int i; - vararg_start(ap, outname); - for (i = 1; (rgargs[i++] = va_arg(ap, char const*)); ) - if (CARGSMAX <= i) - faterror("too many command arguments"); - va_end(ap); - return runv(infd, outname, rgargs); -} - - -int RCSversion; - - void -setRCSversion(str) - char const *str; -{ - static int oldversion; - - register char const *s = str + 2; - - if (*s) { - int v = VERSION_DEFAULT; - - if (oldversion) - redefined('V'); - oldversion = true; - v = 0; - while (isdigit(*s)) - v = 10*v + *s++ - '0'; - if (*s) - error("%s isn't a number", str); - else if (v < VERSION_min || VERSION_max < v) - error("%s out of range %d..%d", - str, VERSION_min, VERSION_max - ); - - RCSversion = VERSION(v); - } else { - printf("RCS version %s\n", RCS_version_string); - exit(0); - } -} - - int -getRCSINIT(argc, argv, newargv) - int argc; - char **argv, ***newargv; -{ - register char *p, *q, **pp; - char const *ev; - size_t n; - - if ((ev = cgetenv("RCSLOCALID"))) - setRCSLocalId(ev); - - if ((ev = cgetenv("RCSINCEXC"))) - setIncExc(ev); - - if (!(q = cgetenv("RCSINIT"))) - *newargv = argv; - else { - n = argc + 2; - /* - * Count spaces in RCSINIT to allocate a new arg vector. - * This is an upper bound, but it's OK even if too large. - */ - for (p = q; ; ) { - switch (*p++) { - default: - continue; - - case ' ': - case '\b': case '\f': case '\n': - case '\r': case '\t': case '\v': - n++; - continue; - - case '\0': - break; - } - break; - } - *newargv = pp = tnalloc(char*, n); - *pp++ = *argv++; /* copy program name */ - for (p = q; ; ) { - for (;;) { - switch (*q) { - case '\0': - goto copyrest; - - case ' ': - case '\b': case '\f': case '\n': - case '\r': case '\t': case '\v': - q++; - continue; - } - break; - } - *pp++ = p; - ++argc; - for (;;) { - switch ((*p++ = *q++)) { - case '\0': - goto copyrest; - - case '\\': - if (!*q) - goto copyrest; - p[-1] = *q++; - continue; - - default: - continue; - - case ' ': - case '\b': case '\f': case '\n': - case '\r': case '\t': case '\v': - break; - } - break; - } - p[-1] = '\0'; - } - copyrest: - while ((*pp++ = *argv++)) - continue; - } - return argc; -} - - -#define cacheid(E) static uid_t i; static int s; if (!s){ s=1; i=(E); } return i - -#if has_getuid - uid_t ruid() { cacheid(getuid()); } -#endif -#if has_setuid - uid_t euid() { cacheid(geteuid()); } -#endif - - -#if has_setuid - -/* - * Setuid execution really works only with Posix 1003.1a Draft 5 seteuid(), - * because it lets us switch back and forth between arbitrary users. - * If seteuid() doesn't work, we fall back on setuid(), - * which works if saved setuid is supported, - * unless the real or effective user is root. - * This area is such a mess that we always check switches at runtime. - */ - - static void -#if has_prototypes -set_uid_to(uid_t u) -#else - set_uid_to(u) uid_t u; -#endif -/* Become user u. */ -{ - static int looping; - - if (euid() == ruid()) - return; -#if (has_fork||has_spawn) && DIFF_ABSOLUTE -# if has_setreuid - if (setreuid(u==euid() ? ruid() : euid(), u) != 0) - efaterror("setuid"); -# else - if (seteuid(u) != 0) - efaterror("setuid"); -# endif -#endif - if (geteuid() != u) { - if (looping) - return; - looping = true; - faterror("root setuid not supported" + (u?5:0)); - } -} - -static int stick_with_euid; - - void -/* Ignore all calls to seteid() and setrid(). */ -nosetid() -{ - stick_with_euid = true; -} - - void -seteid() -/* Become effective user. */ -{ - if (!stick_with_euid) - set_uid_to(euid()); -} - - void -setrid() -/* Become real user. */ -{ - if (!stick_with_euid) - set_uid_to(ruid()); -} -#endif - - time_t -now() -{ - static time_t t; - if (!t && time(&t) == -1) - efaterror("time"); - return t; -} diff --git a/gnu/usr.bin/rcs/lib/version.c b/gnu/usr.bin/rcs/lib/version.c deleted file mode 100644 index 81f5585..0000000 --- a/gnu/usr.bin/rcs/lib/version.c +++ /dev/null @@ -1,2 +0,0 @@ -#include "rcsbase.h" -char const RCS_version_string[] = "5.7"; |