summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/cvs/lib
diff options
context:
space:
mode:
authorThorsten Lockert <tholo@cvs.openbsd.org>1996-04-27 19:43:32 +0000
committerThorsten Lockert <tholo@cvs.openbsd.org>1996-04-27 19:43:32 +0000
commit49126961fd129e607f88970e81ab6d48baaecda0 (patch)
tree8168bd6a7b92392e99d483a83c51b3f8f7df113d /gnu/usr.bin/cvs/lib
parent61aa6f7b30e536382606a49e9a65374b125db338 (diff)
Latest public release from Cyclic; fixes numerous memory leaks and have
some performance improvements
Diffstat (limited to 'gnu/usr.bin/cvs/lib')
-rw-r--r--gnu/usr.bin/cvs/lib/ChangeLog44
-rw-r--r--gnu/usr.bin/cvs/lib/getopt.c4
-rw-r--r--gnu/usr.bin/cvs/lib/regex.c4
-rw-r--r--gnu/usr.bin/cvs/lib/savecwd.c141
-rw-r--r--gnu/usr.bin/cvs/lib/savecwd.h20
-rw-r--r--gnu/usr.bin/cvs/lib/strtoul.c100
-rw-r--r--gnu/usr.bin/cvs/lib/vasprintf.c171
7 files changed, 480 insertions, 4 deletions
diff --git a/gnu/usr.bin/cvs/lib/ChangeLog b/gnu/usr.bin/cvs/lib/ChangeLog
index ce886e0cea7..8fd389913bf 100644
--- a/gnu/usr.bin/cvs/lib/ChangeLog
+++ b/gnu/usr.bin/cvs/lib/ChangeLog
@@ -1,3 +1,47 @@
+Thu Feb 22 22:30:04 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * Makefile.in (OBJECTS): Remove @ALLOCA@
+ (SOURCES): Remove alloca.c
+ * alloca.c: Removed.
+ * regex.c (REGEX_MALLOC): Define.
+
+Thu Feb 15 14:00:00 Jim Kingdon <kingdon@cyclic.com>
+
+ * vasprintf.c: Declare abs().
+
+Wed Feb 14 14:48:31 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * vasprintf.c (int_vasprintf): Don't cast arguments to memcpy.
+ * vasprintf.c, strtoul.c: Don't include ansidecl.h. Do include
+ config.h if HAVE_CONFIG_H (for const).
+ * strtoul.c: Change CONST to const.
+
+Tue Feb 13 20:04:39 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * strtoul.c: Added (needed by vasprintf.c, and missing on SunOS4).
+ * Makefile.in (SOURCES): Add strtoul.c.
+
+Mon Feb 12 10:04:46 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * vasprintf.c: Added (same contents as before).
+ * Makefile.in (SOURCES): Add vasprintf.c.
+
+Thu Feb 1 14:33:17 1996 Karl Fogel <kfogel@floss.red-bean.com>
+
+ * Makefile.in (xlint): new rule; does nothing, as I'm not sure
+ running lint is actually advisable in here, but the top-level
+ Makefile thinks it can `make xlint' here.
+
+Thu Feb 1 15:07:42 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * getopt.c: Remove rcsid.
+
+Tue Jan 30 18:20:27 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * getline.c: Don't define NDEBUG.
+ (getstr): Rewrite assertions in a way which should stay clear of
+ signed/unsigned problems and compiler warnings thereof.
+
Thu Jan 25 00:14:06 1996 Jim Kingdon <kingdon@beezley.cyclic.com>
* yesno.c (yesno): fflush stdout as well as stderr.
diff --git a/gnu/usr.bin/cvs/lib/getopt.c b/gnu/usr.bin/cvs/lib/getopt.c
index f1d8dfa1345..137e66be187 100644
--- a/gnu/usr.bin/cvs/lib/getopt.c
+++ b/gnu/usr.bin/cvs/lib/getopt.c
@@ -84,10 +84,6 @@
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
-#ifndef lint
-static char rcsid[] = "$CVSid: @(#)getopt.c 1.10 94/09/21 $";
-#endif
-
#include "getopt.h"
/* For communication from `getopt' to the caller.
diff --git a/gnu/usr.bin/cvs/lib/regex.c b/gnu/usr.bin/cvs/lib/regex.c
index 6cb25c31245..03fc721f38d 100644
--- a/gnu/usr.bin/cvs/lib/regex.c
+++ b/gnu/usr.bin/cvs/lib/regex.c
@@ -19,6 +19,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+/* Trying to define this in the makefile would get hairy, unless we can
+ more gracefully do it for NT, OS/2, unix, etc. */
+#define REGEX_MALLOC 1
+
/* AIX requires this to be the first thing in the file. */
#if defined (_AIX) && !defined (REGEX_MALLOC)
#pragma alloca
diff --git a/gnu/usr.bin/cvs/lib/savecwd.c b/gnu/usr.bin/cvs/lib/savecwd.c
new file mode 100644
index 00000000000..b5b7cb86a46
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/savecwd.c
@@ -0,0 +1,141 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#else
+# include <sys/file.h>
+#endif
+
+#ifdef HAVE_DIRECT_H
+# include <direct.h>
+#endif
+
+#ifdef HAVE_IO_H
+# include <io.h>
+#endif
+
+#include <errno.h>
+# ifndef errno
+extern int errno;
+#endif
+
+#include "savecwd.h"
+#include "error.h"
+
+char *xgetwd __PROTO((void));
+
+/* Record the location of the current working directory in CWD so that
+ the program may change to other directories and later use restore_cwd
+ to return to the recorded location. This function may allocate
+ space using malloc (via xgetwd) or leave a file descriptor open;
+ use free_cwd to perform the necessary free or close. Upon failure,
+ no memory is allocated, any locally opened file descriptors are
+ closed; return non-zero -- in that case, free_cwd need not be
+ called, but doing so is ok. Otherwise, return zero. */
+
+int
+save_cwd (cwd)
+ struct saved_cwd *cwd;
+{
+ static int have_working_fchdir = 1;
+
+ cwd->desc = -1;
+ cwd->name = NULL;
+
+ if (have_working_fchdir)
+ {
+#ifdef HAVE_FCHDIR
+ cwd->desc = open (".", O_RDONLY);
+ if (cwd->desc < 0)
+ {
+ error (0, errno, "cannot open current directory");
+ return 1;
+ }
+
+# if __sun__ || sun
+ /* On SunOS 4, fchdir returns EINVAL if accounting is enabled,
+ so we have to fall back to chdir. */
+ if (fchdir (cwd->desc))
+ {
+ if (errno == EINVAL)
+ {
+ close (cwd->desc);
+ cwd->desc = -1;
+ have_working_fchdir = 0;
+ }
+ else
+ {
+ error (0, errno, "current directory");
+ close (cwd->desc);
+ cwd->desc = -1;
+ return 1;
+ }
+ }
+# endif /* __sun__ || sun */
+#else
+#define fchdir(x) (abort (), 0)
+ have_working_fchdir = 0;
+#endif
+ }
+
+ if (!have_working_fchdir)
+ {
+ cwd->name = xgetwd ();
+ if (cwd->name == NULL)
+ {
+ error (0, errno, "cannot get current directory");
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Change to recorded location, CWD, in directory hierarchy.
+ If "saved working directory", NULL))
+ */
+
+int
+restore_cwd (cwd, dest)
+ const struct saved_cwd *cwd;
+ const char *dest;
+{
+ int fail = 0;
+ if (cwd->desc >= 0)
+ {
+ if (fchdir (cwd->desc))
+ {
+ error (0, errno, "cannot return to %s",
+ (dest ? dest : "saved working directory"));
+ fail = 1;
+ }
+ }
+ else if (chdir (cwd->name) < 0)
+ {
+ error (0, errno, "%s", cwd->name);
+ fail = 1;
+ }
+ return fail;
+}
+
+void
+free_cwd (cwd)
+ struct saved_cwd *cwd;
+{
+ if (cwd->desc >= 0)
+ close (cwd->desc);
+ if (cwd->name)
+ free (cwd->name);
+}
+
diff --git a/gnu/usr.bin/cvs/lib/savecwd.h b/gnu/usr.bin/cvs/lib/savecwd.h
new file mode 100644
index 00000000000..f9802f8ca2f
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/savecwd.h
@@ -0,0 +1,20 @@
+#ifndef SAVE_CWD_H
+#define SAVE_CWD_H 1
+
+struct saved_cwd
+ {
+ int desc;
+ char *name;
+ };
+
+#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
+#define __PROTO(args) args
+#else
+#define __PROTO(args) ()
+#endif /* GCC. */
+
+int save_cwd __PROTO((struct saved_cwd *cwd));
+int restore_cwd __PROTO((const struct saved_cwd *cwd, const char *dest));
+void free_cwd __PROTO((struct saved_cwd *cwd));
+
+#endif /* SAVE_CWD_H */
diff --git a/gnu/usr.bin/cvs/lib/strtoul.c b/gnu/usr.bin/cvs/lib/strtoul.c
new file mode 100644
index 00000000000..7d42c210f67
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/strtoul.c
@@ -0,0 +1,100 @@
+/*
+ * strtol : convert a string to long.
+ *
+ * Andy Wilson, 2-Oct-89.
+ */
+
+#include <errno.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef ULONG_MAX
+#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */
+#endif
+
+extern int errno;
+
+unsigned long
+strtoul(s, ptr, base)
+ const char *s; char **ptr; int base;
+{
+ unsigned long total = 0;
+ unsigned digit;
+ const char *start=s;
+ int did_conversion=0;
+ int overflow = 0;
+ int negate = 0;
+ unsigned long maxdiv, maxrem;
+
+ if (s==NULL)
+ {
+ errno = ERANGE;
+ if (!ptr)
+ *ptr = (char *)start;
+ return 0L;
+ }
+
+ while (isspace(*s))
+ s++;
+ if (*s == '+')
+ s++;
+ else if (*s == '-')
+ s++, negate = 1;
+ if (base==0 || base==16) /* the 'base==16' is for handling 0x */
+ {
+ int tmp;
+
+ /*
+ * try to infer base from the string
+ */
+ if (*s != '0')
+ tmp = 10; /* doesn't start with 0 - assume decimal */
+ else if (s[1] == 'X' || s[1] == 'x')
+ tmp = 16, s += 2; /* starts with 0x or 0X - hence hex */
+ else
+ tmp = 8; /* starts with 0 - hence octal */
+ if (base==0)
+ base = (int)tmp;
+ }
+
+ maxdiv = ULONG_MAX / base;
+ maxrem = ULONG_MAX % base;
+
+ while ((digit = *s) != '\0')
+ {
+ if (digit >= '0' && digit < ('0'+base))
+ digit -= '0';
+ else
+ if (base > 10)
+ {
+ if (digit >= 'a' && digit < ('a'+(base-10)))
+ digit = digit - 'a' + 10;
+ else if (digit >= 'A' && digit < ('A'+(base-10)))
+ digit = digit - 'A' + 10;
+ else
+ break;
+ }
+ else
+ break;
+ did_conversion = 1;
+ if (total > maxdiv
+ || (total == maxdiv && digit > maxrem))
+ overflow = 1;
+ total = (total * base) + digit;
+ s++;
+ }
+ if (overflow)
+ {
+ errno = ERANGE;
+ if (ptr != NULL)
+ *ptr = (char *)s;
+ return (ULONG_MAX);
+ }
+ if (ptr != NULL)
+ *ptr = (char *) ((did_conversion) ? (char *)s : (char *)start);
+ return negate ? -total : total;
+}
diff --git a/gnu/usr.bin/cvs/lib/vasprintf.c b/gnu/usr.bin/cvs/lib/vasprintf.c
new file mode 100644
index 00000000000..45253b15325
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/vasprintf.c
@@ -0,0 +1,171 @@
+/* Like vsprintf but provides a pointer to malloc'd storage, which must
+ be freed by the caller.
+ Copyright (C) 1994 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+extern int abs ();
+
+#ifdef TEST
+int global_total_width;
+#endif
+
+unsigned long strtoul ();
+char *malloc ();
+
+static int
+int_vasprintf (result, format, args)
+ char **result;
+ const char *format;
+ va_list *args;
+{
+ const char *p = format;
+ /* Add one to make sure that it is never zero, which might cause malloc
+ to return NULL. */
+ int total_width = strlen (format) + 1;
+ va_list ap;
+
+ memcpy (&ap, args, sizeof (va_list));
+
+ while (*p != '\0')
+ {
+ if (*p++ == '%')
+ {
+ while (strchr ("-+ #0", *p))
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, &p, 10);
+ if (*p == '.')
+ {
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, &p, 10);
+ }
+ while (strchr ("hlL", *p))
+ ++p;
+ /* Should be big enough for any format specifier except %s. */
+ total_width += 30;
+ switch (*p)
+ {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ (void) va_arg (ap, int);
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ (void) va_arg (ap, double);
+ break;
+ case 's':
+ total_width += strlen (va_arg (ap, char *));
+ break;
+ case 'p':
+ case 'n':
+ (void) va_arg (ap, char *);
+ break;
+ }
+ }
+ }
+#ifdef TEST
+ global_total_width = total_width;
+#endif
+ *result = malloc (total_width);
+ if (*result != NULL)
+ return vsprintf (*result, format, *args);
+ else
+ return 0;
+}
+
+int
+vasprintf (result, format, args)
+ char **result;
+ const char *format;
+ va_list args;
+{
+ return int_vasprintf (result, format, &args);
+}
+
+#ifdef TEST
+void
+checkit
+#ifdef __STDC__
+ (const char* format, ...)
+#else
+ (va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+ char *result;
+
+#ifdef __STDC__
+ va_start (args, format);
+#else
+ char *format;
+ va_start (args);
+ format = va_arg (args, char *);
+#endif
+ vasprintf (&result, format, args);
+ if (strlen (result) < global_total_width)
+ printf ("PASS: ");
+ else
+ printf ("FAIL: ");
+ printf ("%d %s\n", global_total_width, result);
+}
+
+int
+main ()
+{
+ checkit ("%d", 0x12345678);
+ checkit ("%200d", 5);
+ checkit ("%.300d", 6);
+ checkit ("%100.150d", 7);
+ checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
+777777777777777777333333333333366666666666622222222222777777777777733333");
+ checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
+}
+#endif /* TEST */