summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/GNUmakefile4
-rw-r--r--lib/atou.c30
-rw-r--r--lib/atou.obin4976 -> 0 bytes
-rw-r--r--lib/concatn.c70
-rw-r--r--lib/dir.c85
-rw-r--r--lib/extend-fname.c34
-rw-r--r--lib/find-suffix.c45
-rw-r--r--lib/hash.c180
-rw-r--r--lib/make-suffix.c50
-rw-r--r--lib/progname.c617
-rw-r--r--lib/rm-suffix.c42
-rw-r--r--lib/xcalloc.c35
-rw-r--r--lib/xfopen.c47
-rw-r--r--lib/xfseek.c27
-rw-r--r--lib/xfseek.obin3592 -> 0 bytes
-rw-r--r--lib/xftell.c31
-rw-r--r--lib/xftell.obin3648 -> 0 bytes
-rw-r--r--lib/xmalloc.c41
-rw-r--r--lib/xrealloc.c54
-rw-r--r--lib/xstrdup.c4
20 files changed, 1393 insertions, 3 deletions
diff --git a/lib/GNUmakefile b/lib/GNUmakefile
index ac9a0d7..fbfe941 100644
--- a/lib/GNUmakefile
+++ b/lib/GNUmakefile
@@ -30,7 +30,9 @@ encoding float-ok fmod file-input file-output filename fix-num font \
hexify identity integer-ok libfile line list logreport \
make-prefix math now numtoa pathsrch rand report safe-free scaled-num \
spline statistics str-lcase str-to-bit substring varstring vector \
-xmessage xopendir xrename
+xmessage xopendir xrename \
+atou concatn dir extend-fname find-suffix hash make-suffix progname rm-suffix \
+xcalloc xfopen xfseek xftell xmalloc xrealloc xstrdup
include ../data/defs.make
include ../data/defslib.make
diff --git a/lib/atou.c b/lib/atou.c
new file mode 100644
index 0000000..d2e1cda
--- /dev/null
+++ b/lib/atou.c
@@ -0,0 +1,30 @@
+/* atou.c: like atoi, but if the number is negative, abort.
+
+Copyright (C) 1992, 95 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+
+unsigned
+atou P1C(const_string, s)
+{
+ int i = atoi (s);
+
+ if (i < 0)
+ FATAL1 ("I expected a positive number, not %d", i);
+
+ return i;
+}
diff --git a/lib/atou.o b/lib/atou.o
deleted file mode 100644
index d15e642..0000000
--- a/lib/atou.o
+++ /dev/null
Binary files differ
diff --git a/lib/concatn.c b/lib/concatn.c
new file mode 100644
index 0000000..73f7d26
--- /dev/null
+++ b/lib/concatn.c
@@ -0,0 +1,70 @@
+/* concatn.c: Concatenate an arbitrary number of strings.
+
+Copyright (C) 1993, 95 Karl Berry.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+
+#include <kpathsea/concatn.h>
+
+
+/* OK, it would be epsilon more efficient to compute the total length
+ and then do the copying ourselves, but I doubt it matters in reality. */
+
+string
+concatn PVAR1C(const_string, str1, ap)
+{
+ string arg;
+ string ret;
+
+ if (!str1)
+ return NULL;
+
+ ret = xstrdup (str1);
+
+ while ((arg = va_arg (ap, string)) != NULL)
+ {
+ string temp = concat (ret, arg);
+ free (ret);
+ ret = temp;
+ }
+ va_end (ap);
+
+ return ret;
+}}
+
+#ifdef TEST
+int
+main ()
+{
+ printf ("null = \"%s\"\n", concatn (NULL));
+ printf ("\"a\" = \"%s\"\n", concatn ("a", NULL));
+ printf ("\"ab\" = \"%s\"\n", concatn ("a", "b", NULL));
+ printf ("\"abc\" = \"%s\"\n", concatn ("a", "b", "c", NULL));
+ printf ("\"abcd\" = \"%s\"\n", concatn ("ab", "cd", NULL));
+ printf ("\"abcde\" = \"%s\"\n", concatn ("ab", "c", "de", NULL));
+ printf ("\"abcdef\" = \"%s\"\n", concatn ("", "a", "", "bcd", "ef", NULL));
+ return 0;
+}
+
+#endif /* TEST */
+
+
+/*
+Local variables:
+standalone-compile-command: "gcc -posix -g -I. -I.. -DTEST concatn.c kpathsea.a"
+End:
+*/
diff --git a/lib/dir.c b/lib/dir.c
new file mode 100644
index 0000000..1ca64ae
--- /dev/null
+++ b/lib/dir.c
@@ -0,0 +1,85 @@
+/* dir.c: directory operations.
+
+Copyright (C) 1992, 93, 94, 95, 2004 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+
+#include <kpathsea/c-dir.h>
+#include <kpathsea/c-stat.h>
+#include <kpathsea/hash.h>
+
+
+/* Return true if FN is a directory or a symlink to a directory,
+ false if not. */
+
+boolean
+dir_p P1C(const_string, fn)
+{
+ struct stat stats;
+ return stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode);
+}
+
+
+/* Return -1 if FN isn't a directory, else its number of links.
+ Duplicate the call to stat; no need to incur overhead of a function
+ call for that little bit of cleanliness. */
+
+int
+dir_links P1C(const_string, fn)
+{
+ static hash_table_type link_table;
+ string *hash_ret;
+ long ret;
+
+ if (link_table.size == 0)
+ link_table = hash_create (457);
+
+#ifdef KPSE_DEBUG
+ /* This is annoying, but since we're storing integers as pointers, we
+ can't print them as strings. */
+ if (KPSE_DEBUG_P (KPSE_DEBUG_HASH))
+ kpse_debug_hash_lookup_int = true;
+#endif
+
+ hash_ret = hash_lookup (link_table, fn);
+
+#ifdef KPSE_DEBUG
+ if (KPSE_DEBUG_P (KPSE_DEBUG_HASH))
+ kpse_debug_hash_lookup_int = false;
+#endif
+
+ /* Have to cast the int we need to/from the const_string that the hash
+ table stores for values. Let's hope an int fits in a pointer. */
+ if (hash_ret)
+ ret = (long) *hash_ret;
+ else
+ {
+ struct stat stats;
+ ret = stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode)
+ ? stats.st_nlink : -1;
+
+ /* It's up to us to copy the value. */
+ hash_insert (&link_table, xstrdup (fn), (const_string) ret);
+
+#ifdef KPSE_DEBUG
+ if (KPSE_DEBUG_P (KPSE_DEBUG_STAT))
+ DEBUGF2 ("dir_links(%s) => %ld\n", fn, ret);
+#endif
+ }
+
+ return ret;
+}
diff --git a/lib/extend-fname.c b/lib/extend-fname.c
new file mode 100644
index 0000000..98d118c
--- /dev/null
+++ b/lib/extend-fname.c
@@ -0,0 +1,34 @@
+/* extend-fname.c: give a filename a suffix, if necessary.
+
+Copyright (C) 1992, 93 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+
+
+/* We may or may not return NAME. It's up to the caller not to assume
+ the return value is modifiable. */
+
+string
+extend_filename P2C(const_string, name, const_string, default_suffix)
+{
+ string new_s;
+ const_string suffix = find_suffix (name);
+
+ new_s = suffix == NULL ? concat3 (name, ".", default_suffix)
+ : (string) name;
+ return new_s;
+}
diff --git a/lib/find-suffix.c b/lib/find-suffix.c
new file mode 100644
index 0000000..9774713
--- /dev/null
+++ b/lib/find-suffix.c
@@ -0,0 +1,45 @@
+/* find-suffix.c: return the stuff after a dot.
+
+Copyright (C) 1992, 93 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+
+#include <kpathsea/c-pathch.h>
+
+
+/* Return pointer to first character after `.' in last directory element
+ of NAME. If the name is `foo' or `/foo.bar/baz', we have no extension. */
+
+string
+find_suffix P1C(const_string, name)
+{
+ const_string slash_pos;
+ string dot_pos = strrchr (name, '.');
+
+ if (dot_pos == NULL)
+ return NULL;
+
+ for (slash_pos = name + strlen (name);
+ slash_pos > dot_pos && !IS_DIR_SEP (*slash_pos);
+ slash_pos--)
+ ;
+
+ return slash_pos > dot_pos ? NULL : dot_pos + 1;
+}
+
+
+
diff --git a/lib/hash.c b/lib/hash.c
new file mode 100644
index 0000000..f6450b6
--- /dev/null
+++ b/lib/hash.c
@@ -0,0 +1,180 @@
+/* hash.c: hash table operations.
+
+Copyright (C) 1994, 95, 96 Karl Berry.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+
+#include <kpathsea/hash.h>
+#include <kpathsea/str-list.h>
+
+
+/* The hash function. We go for simplicity here. */
+
+/* All our hash tables are related to filenames. */
+#ifdef MONOCASE_FILENAMES
+#define TRANSFORM(x) toupper (x)
+#else
+#define TRANSFORM(x) (x)
+#endif
+
+static unsigned
+hash P2C(hash_table_type, table, const_string, key)
+{
+ unsigned n = 0;
+
+ /* Our keys aren't often anagrams of each other, so no point in
+ weighting the characters. */
+ while (*key != 0)
+ n = (n + n + TRANSFORM (*key++)) % table.size;
+
+ return n;
+}
+
+hash_table_type
+hash_create P1C(unsigned, size)
+{
+ unsigned b;
+ hash_table_type ret;
+ ret.buckets = XTALLOC (size, hash_element_type *);
+ ret.size = size;
+
+ /* calloc's zeroes aren't necessarily NULL, according to ANSI, so be
+ safe. (Not that I know of any exceptions in reality.) */
+ for (b = 0; b <ret.size; b++)
+ ret.buckets[b] = NULL;
+
+ return ret;
+}
+
+/* Whether or not KEY is already in MAP, insert it and VALUE. Do not
+ duplicate the strings, in case they're being purposefully shared. */
+
+void
+hash_insert P3C(hash_table_type *, table, const_string, key,
+ const_string, value)
+{
+ unsigned n = hash (*table, key);
+ hash_element_type *new_elt = XTALLOC1 (hash_element_type);
+
+ new_elt->key = key;
+ new_elt->value = value;
+ new_elt->next = NULL;
+
+ /* Insert the new element at the end of the list. */
+ if (!table->buckets[n])
+ /* first element in bucket is a special case. */
+ table->buckets[n] = new_elt;
+ else
+ {
+ hash_element_type *loc = table->buckets[n];
+ while (loc->next) /* Find the last element. */
+ loc = loc->next;
+ loc->next = new_elt; /* Insert the new one after. */
+ }
+}
+
+/* Look up STR in MAP. Return a (dynamically-allocated) list of the
+ corresponding strings or NULL if no match. */
+
+#ifdef KPSE_DEBUG
+/* Print the hash values as integers if this is nonzero. */
+boolean kpse_debug_hash_lookup_int = false;
+#endif
+
+string *
+hash_lookup P2C(hash_table_type, table, const_string, key)
+{
+ hash_element_type *p;
+ str_list_type ret;
+ unsigned n = hash (table, key);
+ ret = str_list_init ();
+
+ /* Look at everything in this bucket. */
+ for (p = table.buckets[n]; p != NULL; p = p->next)
+ if (FILESTRCASEEQ (key, p->key))
+ /* Cast because the general str_list_type shouldn't force const data. */
+ str_list_add (&ret, (string) p->value);
+
+ /* If we found anything, mark end of list with null. */
+ if (STR_LIST (ret))
+ str_list_add (&ret, NULL);
+
+#ifdef KPSE_DEBUG
+ if (KPSE_DEBUG_P (KPSE_DEBUG_HASH))
+ {
+ DEBUGF1 ("hash_lookup(%s) =>", key);
+ if (!STR_LIST (ret))
+ fputs (" (nil)\n", stderr);
+ else
+ {
+ string *r;
+ for (r = STR_LIST (ret); *r; r++)
+ {
+ putc (' ', stderr);
+ if (kpse_debug_hash_lookup_int)
+ fprintf (stderr, "%ld", (long) *r);
+ else
+ fputs (*r, stderr);
+ }
+ putc ('\n', stderr);
+ }
+ fflush (stderr);
+ }
+#endif
+
+ return STR_LIST (ret);
+}
+
+/* We only print nonempty buckets, to decrease output volume. */
+
+void
+hash_print P2C(hash_table_type, table, boolean, summary_only)
+{
+ unsigned b;
+ unsigned total_elements = 0, total_buckets = 0;
+
+ for (b = 0; b < table.size; b++) {
+ hash_element_type *bucket = table.buckets[b];
+
+ if (bucket) {
+ unsigned len = 1;
+ hash_element_type *tb;
+
+ total_buckets++;
+ if (!summary_only) fprintf (stderr, "%4d ", b);
+
+ for (tb = bucket->next; tb != NULL; tb = tb->next)
+ len++;
+ if (!summary_only) fprintf (stderr, ":%-5d", len);
+ total_elements += len;
+
+ if (!summary_only) {
+ for (tb = bucket; tb != NULL; tb = tb->next)
+ fprintf (stderr, " %s=>%s", tb->key, tb->value);
+ putc ('\n', stderr);
+ }
+ }
+ }
+
+ fprintf (stderr,
+ "%u buckets, %u nonempty (%u%%); %u entries, average chain %.1f.\n",
+ table.size,
+ total_buckets,
+ 100 * total_buckets / table.size,
+ total_elements,
+ total_buckets ? total_elements / (double) total_buckets : 0.0);
+}
diff --git a/lib/make-suffix.c b/lib/make-suffix.c
new file mode 100644
index 0000000..1935c3f
--- /dev/null
+++ b/lib/make-suffix.c
@@ -0,0 +1,50 @@
+/* make-suffix.c: unconditionally add a filename suffix.
+
+Copyright (C) 1992, 93, 95 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+#include <kpathsea/c-pathch.h>
+
+/* Return a new string: S suffixed with SUFFIX, regardless of what it
+ was before. This returns a newly allocated string. */
+
+string
+make_suffix P2C(const_string, s, const_string, suffix)
+{
+ string new_s;
+ const_string dot_pos = strrchr (s, '.');
+ const_string slash_pos;
+
+ for (slash_pos = s + strlen (s) - 1; slash_pos > dot_pos && slash_pos > s;
+ slash_pos--) {
+ if (IS_DIR_SEP (*slash_pos))
+ break;
+ }
+
+ if (dot_pos == NULL || slash_pos > dot_pos )
+ new_s = concat3 (s, ".", suffix);
+ else
+ {
+ unsigned past_dot_index = dot_pos + 1 - s;
+
+ new_s = xmalloc (past_dot_index + strlen (suffix) + 1);
+ strncpy (new_s, s, dot_pos + 1 - s);
+ strcpy (new_s + past_dot_index, suffix);
+ }
+
+ return new_s;
+}
diff --git a/lib/progname.c b/lib/progname.c
new file mode 100644
index 0000000..d269e2f
--- /dev/null
+++ b/lib/progname.c
@@ -0,0 +1,617 @@
+/* progname.c: the executable name we were invoked as; general initialization.
+
+Copyright (C) 1994, 96, 97 Karl Berry.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+#include <kpathsea/absolute.h>
+#include <kpathsea/c-pathch.h>
+#include <kpathsea/c-stat.h>
+#include <kpathsea/pathsearch.h>
+/* For kpse_reset_progname */
+#include <kpathsea/tex-file.h>
+
+#ifdef WIN32
+#include <kpathsea/c-pathmx.h>
+#endif
+
+/* NeXT does not define the standard macros, but has the equivalent.
+ WIN32 doesn't define them either, and doesn't have them.
+ From: Gregor Hoffleit <flight@mathi.uni-heidelberg.de>. */
+#ifndef S_IXUSR
+#ifdef WIN32
+#define S_IXUSR 0
+#define S_IXGRP 0
+#define S_IXOTH 0
+#else /* not WIN32 */
+#define S_IXUSR 0100
+#endif /* not WIN32 */
+#endif /* not S_IXUSR */
+#ifndef S_IXGRP
+#define S_IXGRP 0010
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH 0001
+#endif
+
+#ifndef HAVE_PROGRAM_INVOCATION_NAME
+/* Don't redefine the variables if glibc already has. */
+string program_invocation_name = NULL;
+string program_invocation_short_name = NULL;
+#endif
+/* And the variable for the program we pretend to be. */
+string kpse_program_name = NULL;
+
+/* Return directory for NAME. This is "." if NAME contains no directory
+ separators (should never happen for selfdir), else whatever precedes
+ the final directory separator, but with multiple separators stripped.
+ For example, `my_dirname ("/foo//bar.baz")' returns "/foo". Always
+ return a new string. */
+
+static string
+my_dirname P1C(const_string, name)
+{
+ string ret;
+ unsigned loc = strlen (name);
+
+ for (loc = strlen (name); loc > 0 && !IS_DIR_SEP (name[loc-1]); loc--)
+ ;
+
+ if (loc) {
+ /* If have ///a, must return /, so don't strip off everything. */
+ unsigned limit = NAME_BEGINS_WITH_DEVICE (name) ? 3 : 1;
+ while (loc > limit && IS_DIR_SEP (name[loc-1])
+ && !IS_DEVICE_SEP (name[loc-1])) {
+ loc--;
+ }
+ ret = xmalloc (loc + 1);
+ strncpy (ret, name, loc);
+ ret[loc] = 0;
+ } else {
+ /* No directory separators at all, so return the current directory.
+ The way this is used in kpathsea, this should never happen. */
+ ret = xstrdup (".");
+ }
+
+ return ret;
+}
+
+#ifndef WIN32
+/* From a standalone program `ll' to expand symlinks written by Kimbo Mundy.
+ Don't bother to compile if we don't have symlinks; thus we can assume
+ / as the separator. Also don't try to use basename, etc., or
+ handle arbitrary filename length. Mixed case function names because
+ that's what kimbo liked. */
+
+#ifdef S_ISLNK
+static int ll_verbose = 0;
+static int ll_loop = 0;
+
+#undef BSIZE
+#define BSIZE 2048 /* sorry */
+
+
+/* Read link FN into SYM. */
+
+static void
+ReadSymLink (fn, sym)
+ char *fn, *sym;
+{
+ register int n = readlink (fn, sym, BSIZE);
+ if (n < 0) {
+ perror (fn);
+ exit (1);
+ }
+ sym[n] = 0;
+}
+
+
+/* Strip first component from S, and also return it in a static buffer. */
+
+static char *
+StripFirst (s)
+ register char *s;
+{
+ static char buf[BSIZE];
+ register char *s1;
+
+ /* Find the end of the first path element */
+ for (s1 = s; *s1 && (*s1 != '/' || s1 == s); s1++)
+ ;
+
+ /* Copy it into buf and null-terminate it. */
+ strncpy (buf, s, s1 - s);
+ buf[s1 - s] = 0;
+
+ /* Skip over the leading / (if any) */
+ if (*s1 == '/')
+ ++s1;
+
+ /* Squeeze out the element */
+ while ((*s++ = *s1++) != 0)
+ ;
+
+ return buf;
+}
+
+
+/* Strip last component from S, and also return it in a static buffer. */
+
+static char *
+StripLast (s)
+ register char *s;
+{
+ static char buf[BSIZE];
+ register char *s1;
+
+ for (s1 = s + strlen (s); s1 > s && *s1 != '/'; s1--)
+ ;
+ strcpy (buf, s1 + (*s1 == '/'));
+ *s1 = 0;
+
+ return buf;
+}
+
+
+/* Copy first path element from B to A, removing it from B. */
+
+static void
+CopyFirst (a, b)
+ register char *a;
+ char *b;
+{
+ register int length = strlen (a);
+
+ if (length > 0 && a[length - 1] != '/') {
+ a[length] = '/';
+ a[length + 1] = 0;
+ }
+ strcat (a, StripFirst (b));
+}
+
+/* Returns NULL on error. Prints intermediate results if global
+ `ll_verbose' is nonzero. */
+
+#define EX(s) (strlen (s) && strcmp (s, "/") ? "/" : "")
+#define EXPOS EX(post)
+#define EXPRE EX(pre)
+
+static char *
+expand_symlinks (s)
+ char *s;
+{
+ static char pre[BSIZE]; /* return value */
+ char post[BSIZE], sym[BSIZE], tmp[BSIZE], before[BSIZE];
+ char *cp;
+ char a;
+ struct stat st;
+ int done;
+
+ /* Check for symlink loops. It's difficult to check for all the
+ possibilities ourselves, so let the kernel do it. And make it
+ conditional so that people can see where the infinite loop is
+ being caused (see engtools#1536). */
+ if (!ll_loop) {
+ FILE *f = fopen (s, "r");
+ if (!f && errno == ELOOP) {
+ /* Not worried about other errors, we'll get to them in due course. */
+ perror (s);
+ return NULL;
+ }
+ if (f) fclose (f);
+ }
+
+ strcpy (post, s);
+ strcpy (pre, "");
+
+ while (strlen (post) != 0) {
+ CopyFirst (pre, post);
+
+ if (lstat (pre, &st) != 0) {
+ fprintf (stderr, "lstat(%s) failed ...\n", pre);
+ perror (pre);
+ return NULL;
+ }
+
+ if (S_ISLNK (st.st_mode)) {
+ ReadSymLink (pre, sym);
+
+ if (!strncmp (sym, "/", 1)) {
+ if (ll_verbose)
+ printf ("[%s]%s%s -> [%s]%s%s\n", pre, EXPOS, post, sym, EXPOS,post);
+ strcpy (pre, "");
+
+ } else {
+ a = pre[0]; /* handle links through the root */
+ strcpy (tmp, StripLast (pre));
+ if (!strlen (pre) && a == '/')
+ strcpy (pre, "/");
+
+ if (ll_verbose) {
+ sprintf (before, "%s%s[%s]%s%s", pre, EXPRE, tmp, EXPOS, post);
+ printf ("%s -> %s%s[%s]%s%s\n", before, pre, EXPRE, sym, EXPOS,post);
+ }
+
+ /* Strip "../" path elements from the front of sym; print
+ new result if there were any such elements. */
+ done = 0;
+ a = pre[0]; /* handle links through the root */
+ while (!strncmp (sym, "..", 2)
+ && (sym[2] == 0 || sym[2] == '/')
+ && strlen (pre) != 0
+ && strcmp (pre, ".")
+ && strcmp (pre, "..")
+ && (strlen (pre) < 3
+ || strcmp (pre + strlen (pre) - 3, "/.."))) {
+ done = 1;
+ StripFirst (sym);
+ StripLast (pre);
+ }
+
+ if (done && ll_verbose) {
+ for (cp = before; *cp;)
+ *cp++ = ' ';
+ if (strlen (sym))
+ printf ("%s == %s%s%s%s%s\n", before, pre, EXPRE, sym, EXPOS,post);
+ else
+ printf ("%s == %s%s%s\n", before, pre, EXPOS, post);
+ }
+ if (!strlen (pre) && a == '/')
+ strcpy (pre, "/");
+ }
+
+ if (strlen (post) != 0 && strlen (sym) != 0)
+ strcat (sym, "/");
+
+ strcat (sym, post);
+ strcpy (post, sym);
+ }
+ }
+
+ return pre;
+}
+#else /* not S_ISLNK */
+#define expand_symlinks(s) (s)
+#endif /* not S_ISLNK */
+
+/* Remove .'s and ..'s in DIR, to avoid problems with relative symlinks
+ as the program name, etc. This does not canonicalize symlinks. */
+
+static string
+remove_dots P1C(string, dir)
+{
+#ifdef AMIGA
+ return dir;
+#else
+ string c;
+ unsigned len;
+ string ret = (string) ""; /* We always reassign. */
+
+ for (c = kpse_filename_component (dir); c;
+ c = kpse_filename_component (NULL)) {
+ if (STREQ (c, ".")) {
+ /* If leading ., replace with cwd. Else ignore. */
+ if (*ret == 0) {
+ ret = xgetcwd ();
+ }
+
+ } else if (STREQ (c, "..")) {
+ /* If leading .., start with my_dirname (cwd). Else remove last
+ component from ret, if any. */
+ if (*ret == 0) {
+ string dot = xgetcwd ();
+ ret = my_dirname (dot);
+ free (dot);
+ } else {
+ unsigned last;
+ for (last = strlen (ret);
+ last > (NAME_BEGINS_WITH_DEVICE (ret) ? 2 : 0);
+ last--) {
+ if (IS_DIR_SEP (ret[last - 1])) {
+ /* If we have `/../', that's the same as `/'. */
+ if (last > 1) {
+ ret[last] = 0;
+ }
+ break;
+ }
+ }
+ }
+
+ } else {
+ /* Not . or ..; just append. Include a directory separator unless
+ our string already ends with one. This also changes all directory
+ separators into the canonical DIR_SEP_STRING. */
+ string temp;
+ len = strlen (ret);
+ temp = concat3 (ret, ((len > 0 && ret[len - 1] == DIR_SEP)
+ || (NAME_BEGINS_WITH_DEVICE (c) && *ret == 0))
+ ? "" : DIR_SEP_STRING,
+ c);
+ if (*ret)
+ free (ret);
+ ret = temp;
+ }
+ }
+
+ /* Remove a trailing /, just in case it snuck in. */
+ len = strlen (ret);
+ if (len > 0 && ret[len - 1] == DIR_SEP) {
+ ret[len - 1] = 0;
+ }
+
+ return ret;
+#endif /* not AMIGA */
+}
+
+/* Return directory ARGV0 comes from. Check PATH if ARGV0 is not
+ absolute. */
+
+static string
+selfdir P1C(const_string, argv0)
+{
+ string ret = NULL;
+ string self = NULL;
+
+ if (kpse_absolute_p (argv0, true)) {
+ self = xstrdup (argv0);
+ } else {
+#ifdef AMIGA
+#include <dos.h>
+#include <proto/dos.h>
+#include <proto/exec.h>
+ BPTR lock;
+ struct DosLibrary *DOSBase
+ = (struct DosLibrary *) OpenLibrary ("dos.library", 0L);
+ assert (DOSBase);
+
+ self = xmalloc (BUFSIZ);
+ lock = findpath (argv0);
+ if (lock != ((BPTR) -1)) {
+ if (getpath (lock, self) == -1) {
+ *self = '\0';
+ } else {
+ strcat (self,DIR_SEP_STRING);
+ strcat (self,argv0);
+ }
+ UnLock (lock);
+ }
+ CloseLibrary((struct Library *) DOSBase);
+#else /* not AMIGA */
+ string elt;
+ struct stat s;
+
+ /* Have to check PATH. But don't call kpse_path_search since we don't
+ want to search any ls-R's or do anything special with //'s. */
+ for (elt = kpse_path_element (getenv ("PATH")); !self && elt;
+ elt = kpse_path_element (NULL)) {
+ string name = concat3 (elt, DIR_SEP_STRING, argv0);
+
+ /* In order to do this perfectly, we'd have to check the owner bits only
+ if we are the file owner, and the group bits only if we belong
+ to the file group. That's a lot of work, though, and it's not
+ likely that kpathsea will ever be used with a program that's
+ only executable by some classes and not others. See the
+ `file_status' function in execute_cmd.c in bash for what's
+ necessary if we were to do it right. */
+ if (stat (name, &s) == 0 && s.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) {
+ /* Do not stop at directories. */
+ if (!S_ISDIR(s.st_mode))
+ self = name;
+ }
+ }
+#endif /* not AMIGA */
+ }
+
+ /* If argv0 is somehow dir/exename, `self' will still be NULL. */
+ if (!self)
+ self = concat3 (".", DIR_SEP_STRING, argv0);
+
+ ret = my_dirname (remove_dots (expand_symlinks (self)));
+
+ free (self);
+
+ return ret;
+}
+#endif /* not WIN32 */
+
+void
+kpse_set_program_name P2C(const_string, argv0, const_string, progname)
+{
+ string ext, sdir, sdir_parent, sdir_grandparent;
+ string s = getenv ("KPATHSEA_DEBUG");
+#ifdef WIN32
+ string debug_output = getenv("KPATHSEA_DEBUG_OUTPUT");
+ int err, olderr;
+#endif
+
+ /* Set debugging stuff first, in case we end up doing debuggable stuff
+ during this initialization. */
+ if (s) {
+ kpathsea_debug |= atoi (s);
+ }
+
+#ifndef HAVE_PROGRAM_INVOCATION_NAME
+#if defined(WIN32)
+ /* redirect stderr to debug_output. Easier to send logfiles. */
+ if (debug_output) {
+ if ((err = _open(debug_output, _O_CREAT | _O_TRUNC | _O_RDWR,
+ _S_IREAD | _S_IWRITE)) == -1) {
+ WARNING1("Can't open %s for stderr redirection!\n", debug_output);
+ perror(debug_output);
+ } else if ((olderr = _dup(fileno(stderr))) == -1) {
+ WARNING("Can't dup() stderr!\n");
+ close(err);
+ } else if (_dup2(err, fileno(stderr)) == -1) {
+ WARNING1("Can't redirect stderr to %s!\n", debug_output);
+ close(olderr);
+ close(err);
+ } else {
+ close(err);
+ }
+ }
+ /* Win95 always gives the short filename for argv0, not the long one.
+ There is only this way to catch it. It makes all the selfdir stuff
+ useless for win32. */
+ {
+ char path[PATH_MAX], *fp;
+ HANDLE hnd;
+ WIN32_FIND_DATA ffd;
+
+ /* SearchPath() always gives back an absolute directory */
+ if (SearchPath(NULL, argv0, ".exe", PATH_MAX, path, &fp) == 0)
+ FATAL1("Can't determine where the executable %s is.\n", argv0);
+ if ((hnd = FindFirstFile(path, &ffd)) == NULL)
+ FATAL1("The following path points to an invalid file : %s\n", path);
+ /* slashify the dirname */
+ for (fp = path; fp && *fp; fp++)
+ if (IS_DIR_SEP(*fp)) *fp = DIR_SEP;
+ /* sdir will be the directory where the executable resides, ie: c:/TeX/bin */
+ sdir = my_dirname(path);
+ program_invocation_name = xstrdup(ffd.cFileName);
+ }
+
+#elif defined(__DJGPP__)
+
+ /* DJGPP programs support long filenames on Windows 95, but ARGV0 there
+ is always made with the short 8+3 aliases of all the pathname elements.
+ If long names are supported, we need to convert that to a long name.
+
+ All we really need is to call `_truename', but most of the code
+ below is required to deal with the special case of networked drives. */
+ if (pathconf (argv0, _PC_NAME_MAX) > 12) {
+ char long_progname[PATH_MAX];
+
+ if (_truename (argv0, long_progname)) {
+ char *fp;
+
+ if (long_progname[1] != ':') {
+ /* A complication: `_truename' returns network-specific string at
+ the beginning of `long_progname' when the program resides on a
+ networked drive, and DOS calls cannot grok such pathnames. We
+ need to convert the filesystem name back to a drive letter. */
+ char rootname[PATH_MAX], rootdir[4];
+
+ if (argv0[0] && argv0[1] == ':')
+ rootdir[0] = argv0[0]; /* explicit drive in `argv0' */
+ else
+ rootdir[0] = getdisk () + 'A';
+ rootdir[1] = ':';
+ rootdir[2] = '\\';
+ rootdir[3] = '\0';
+ if (_truename (rootdir, rootname)) {
+ /* Find out where `rootname' ends in `long_progname' and replace
+ it with the drive letter. */
+ int root_len = strlen (rootname);
+
+ if (IS_DIR_SEP (rootname[root_len - 1]))
+ root_len--; /* keep the trailing slash */
+ long_progname[0] = rootdir[0];
+ long_progname[1] = ':';
+ memmove (long_progname + 2, long_progname + root_len,
+ strlen (long_progname + root_len) + 1);
+ }
+ }
+
+ /* Convert everything to canonical form. */
+ if (long_progname[0] >= 'A' && long_progname[0] <= 'Z')
+ long_progname[0] += 'a' - 'A'; /* make drive lower case, for beauty */
+ for (fp = long_progname; *fp; fp++)
+ if (IS_DIR_SEP (*fp))
+ *fp = DIR_SEP;
+
+ program_invocation_name = xstrdup (long_progname);
+ }
+ else
+ /* If `_truename' failed, God help them, because we won't... */
+ program_invocation_name = xstrdup (argv0);
+ }
+ else
+ program_invocation_name = xstrdup (argv0);
+
+#else /* !WIN32 && !__DJGPP__ */
+
+ program_invocation_name = xstrdup (argv0);
+
+#endif
+#endif /* not HAVE_PROGRAM_INVOCATION_NAME */
+
+ /* We need to find SELFAUTOLOC *before* removing the ".exe" suffix from
+ the program_name, otherwise the PATH search inside selfdir will fail,
+ since `prog' doesn't exists as a file, there's `prog.exe' instead. */
+#ifndef WIN32
+ sdir = selfdir (program_invocation_name);
+#endif
+ /* SELFAUTODIR is actually the parent of the invocation directory,
+ and SELFAUTOPARENT the grandparent. This is how teTeX did it. */
+ xputenv ("SELFAUTOLOC", sdir);
+ sdir_parent = my_dirname (sdir);
+ xputenv ("SELFAUTODIR", sdir_parent);
+ sdir_grandparent = my_dirname (sdir_parent);
+ xputenv ("SELFAUTOPARENT", sdir_grandparent);
+
+ free (sdir);
+ free (sdir_parent);
+ free (sdir_grandparent);
+
+#ifndef PROGRAM_INVOCATION_NAME
+ program_invocation_short_name = (string)basename (program_invocation_name);
+#endif
+
+ if (progname) {
+ kpse_program_name = xstrdup (progname);
+ } else {
+ /* If configured --enable-shared and running from the build directory
+ with the wrapper scripts (e.g., for make check), the binaries will
+ be named foo.exe instead of foo. Or possibly if we're running on a
+ DOSISH system. */
+ ext = find_suffix (program_invocation_short_name);
+ if (ext && FILESTRCASEEQ (ext, "exe")) {
+ kpse_program_name = remove_suffix (program_invocation_short_name);
+ } else {
+ kpse_program_name = xstrdup (program_invocation_short_name);
+ }
+ }
+}
+
+/* This function is deprecated, because when we pretend to have a different
+ name it will look for _that_ name in the PATH if program_invocation_name
+ is not defined. */
+void
+kpse_set_progname P1C(const_string, argv0)
+{
+ kpse_set_program_name (argv0, NULL);
+}
+
+#ifdef TEST
+void
+main (int argc, char **argv)
+{
+ puts (remove_dots ("/w/kpathsea"));
+ puts (remove_dots ("/w//kpathsea"));
+ puts (remove_dots ("/w/./kpathsea"));
+ puts (remove_dots ("."));
+ puts (remove_dots ("./"));
+ puts (remove_dots ("./."));
+ puts (remove_dots ("../kpathsea"));
+ puts (remove_dots ("/../w/kpathsea"));
+ puts (remove_dots ("/../w/kpathsea/."));
+}
+/*
+Local variables:
+standalone-compile-command: "gcc -g -I. -I.. -DTEST progname.c STATIC/libkpathsea.a"
+End:
+*/
+#endif /* TEST */
diff --git a/lib/rm-suffix.c b/lib/rm-suffix.c
new file mode 100644
index 0000000..192fe10
--- /dev/null
+++ b/lib/rm-suffix.c
@@ -0,0 +1,42 @@
+/* rm-suffix.c: remove any suffix.
+
+Copyright (C) 1992, 93, 95 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+
+
+/* Generic const warning -- see extend-fname.c. */
+
+string
+remove_suffix P1C(const_string, s)
+{
+ string ret;
+ const_string suffix = find_suffix (s);
+
+ if (suffix)
+ {
+ /* Back up to before the dot. */
+ suffix--;
+ ret = (string) xmalloc (suffix - s + 1);
+ strncpy (ret, s, suffix - s);
+ ret[suffix - s] = 0;
+ }
+ else
+ ret = (string) s;
+
+ return ret;
+}
diff --git a/lib/xcalloc.c b/lib/xcalloc.c
new file mode 100644
index 0000000..0d2d52b
--- /dev/null
+++ b/lib/xcalloc.c
@@ -0,0 +1,35 @@
+/* xcalloc.c: calloc with error checking.
+
+Copyright (C) 1992, 93 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+
+
+address
+xcalloc P2C(unsigned, nelem, unsigned, elsize)
+{
+ address new_mem = (address) calloc (nelem, elsize);
+
+ if (new_mem == NULL)
+ {
+ fprintf (stderr, "xcalloc: request for %u elements of size %u failed.\n",
+ nelem, elsize);
+ abort ();
+ }
+
+ return new_mem;
+}
diff --git a/lib/xfopen.c b/lib/xfopen.c
new file mode 100644
index 0000000..084e128
--- /dev/null
+++ b/lib/xfopen.c
@@ -0,0 +1,47 @@
+/* xfopen.c: fopen and fclose with error checking.
+
+Copyright (C) 1992, 93, 95 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+
+
+/* These routines just check the return status from standard library
+ routines and abort if an error happens. */
+
+FILE *
+xfopen P2C(const_string, filename, const_string, mode)
+{
+ FILE *f;
+
+ assert (filename && mode);
+
+ f = fopen (filename, mode);
+ if (f == NULL)
+ FATAL_PERROR (filename);
+
+ return f;
+}
+
+
+void
+xfclose P2C(FILE *, f, const_string, filename)
+{
+ assert (f);
+
+ if (fclose (f) == EOF)
+ FATAL_PERROR (filename);
+}
diff --git a/lib/xfseek.c b/lib/xfseek.c
new file mode 100644
index 0000000..b104383
--- /dev/null
+++ b/lib/xfseek.c
@@ -0,0 +1,27 @@
+/* xfseek.c: fseek with error checking.
+
+Copyright (C) 1992, 95 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+
+
+void
+xfseek P4C(FILE *, f, long, offset, int, wherefrom, string, filename)
+{
+ if (fseek (f, offset, wherefrom) < 0)
+ FATAL_PERROR (filename);
+}
diff --git a/lib/xfseek.o b/lib/xfseek.o
deleted file mode 100644
index fc2e725..0000000
--- a/lib/xfseek.o
+++ /dev/null
Binary files differ
diff --git a/lib/xftell.c b/lib/xftell.c
new file mode 100644
index 0000000..5b421c6
--- /dev/null
+++ b/lib/xftell.c
@@ -0,0 +1,31 @@
+/* xftell.c: ftell with error checking.
+
+Copyright (C) 1992, 93, 95 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <kpathsea/config.h>
+
+
+unsigned long
+xftell P2C(FILE *, f, string, filename)
+{
+ long where = ftell (f);
+
+ if (where < 0)
+ FATAL_PERROR (filename);
+
+ return where;
+}
diff --git a/lib/xftell.o b/lib/xftell.o
deleted file mode 100644
index 0dfe6f8..0000000
--- a/lib/xftell.o
+++ /dev/null
Binary files differ
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
new file mode 100644
index 0000000..0371d43
--- /dev/null
+++ b/lib/xmalloc.c
@@ -0,0 +1,41 @@
+/* xmalloc.c: malloc with error checking.
+
+Copyright (C) 1992, 93 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Don't include config.h or all our other usual includes, since
+ it's useful to just throw this file into other programs. */
+
+#include <stdio.h>
+extern char *malloc ();
+
+
+void *
+xmalloc (size)
+ unsigned size;
+{
+ void *new_mem = (void *) malloc (size);
+
+ if (new_mem == NULL)
+ {
+ fprintf (stderr, "fatal: memory exhausted (xmalloc of %u bytes).\n",
+ size);
+ /* 1 means success on VMS, so pick a random number (ASCII `K'). */
+ exit (75);
+ }
+
+ return new_mem;
+}
diff --git a/lib/xrealloc.c b/lib/xrealloc.c
new file mode 100644
index 0000000..c479b98
--- /dev/null
+++ b/lib/xrealloc.c
@@ -0,0 +1,54 @@
+/* xrealloc.c: realloc with error checking.
+
+Copyright (C) 1992, 93 Free Software Foundation, Inc.
+
+This library 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.
+
+This library 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Don't include config.h or all our other usual includes, since
+ it's useful to just throw this file into other programs. */
+
+#include <stdio.h>
+extern char *realloc ();
+
+
+extern void *xmalloc ();
+
+void *
+xrealloc (old_ptr, size)
+ void *old_ptr;
+ unsigned size;
+{
+ void *new_mem;
+
+ if (old_ptr == NULL)
+ new_mem = xmalloc (size);
+ else
+ {
+ new_mem = (void *) realloc (old_ptr, size);
+ if (new_mem == NULL)
+ {
+ /* We used to print OLD_PTR here using %x, and casting its
+ value to unsigned, but that lost on the Alpha, where
+ pointers and unsigned had different sizes. Since the info
+ is of little or no value anyway, just don't print it. */
+ fprintf (stderr, "fatal: memory exhausted (realloc of %u bytes).\n",
+ size);
+ /* 1 means success on VMS, so pick a random number (ASCII `B'). */
+ exit (66);
+ }
+ }
+
+ return new_mem;
+}
diff --git a/lib/xstrdup.c b/lib/xstrdup.c
index 3ce69e9..f0ca8db 100644
--- a/lib/xstrdup.c
+++ b/lib/xstrdup.c
@@ -1,6 +1,6 @@
/* xstrdup.c: strdup with error checking.
-Copyright (C) 1992 Free Software Foundation, Inc.
+Copyright (C) 1992, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Return a copy of S in new storage. */
string
-xstrdup P1C(string, s)
+xstrdup P1C(const_string, s)
{
string new_string = (string) xmalloc (strlen (s) + 1);
return strcpy (new_string, s);