diff options
author | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-04-27 19:43:32 +0000 |
---|---|---|
committer | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-04-27 19:43:32 +0000 |
commit | 49126961fd129e607f88970e81ab6d48baaecda0 (patch) | |
tree | 8168bd6a7b92392e99d483a83c51b3f8f7df113d /gnu/usr.bin/cvs/lib | |
parent | 61aa6f7b30e536382606a49e9a65374b125db338 (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/ChangeLog | 44 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/lib/getopt.c | 4 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/lib/regex.c | 4 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/lib/savecwd.c | 141 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/lib/savecwd.h | 20 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/lib/strtoul.c | 100 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/lib/vasprintf.c | 171 |
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 */ |