/* argmatch.h -- definitions and prototypes for argmatch.c
- Copyright (C) 1990, 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1998, 1999, 2001 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
/* Programmer friendly interface to __xargmatch_internal. */
-# define XARGMATCH(Context, Arg, Arglist, Vallist) \
+# define XARGMATCH(Context, Arg, Arglist, Vallist) \
(Vallist [__xargmatch_internal ((Context), (Arg), (Arglist), \
(const char *) (Vallist), \
sizeof (*(Vallist)), \
const char *vallist, size_t valsize));
# define ARGMATCH_TO_ARGUMENT(Value, Arglist, Vallist) \
- argmatch_to_argument ((char const *) &(Value), (Arglist), \
+ argmatch_to_argument ((Value), (Arglist), \
(const char *) (Vallist), sizeof (*(Vallist)))
#endif /* ARGMATCH_H_ */
# include <config.h>
#endif
-#include <stdio.h>
-#include <assert.h>
-
-#ifndef FILESYSTEM_PREFIX_LEN
-# define FILESYSTEM_PREFIX_LEN(Filename) 0
-#endif
-
-#ifndef PARAMS
-# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
-# define PARAMS(Args) Args
-# else
-# define PARAMS(Args) ()
-# endif
-#endif
-
-#ifndef ISSLASH
-# define ISSLASH(C) ((C) == '/')
+#if STDC_HEADERS || HAVE_STRING_H
+# include <string.h>
#endif
-
-char *base_name PARAMS ((char const *name));
+#include "dirname.h"
/* In general, we can't use the builtin `basename' function if available,
since it has different meanings in different environments.
In some environments the builtin `basename' modifies its argument.
- If NAME is all slashes, be sure to return `/'. */
+
+ Return the address of the last file name component of NAME. If
+ NAME has no file name components because it is all slashes, return
+ NAME if it is empty, the address of its last slash otherwise. */
char *
base_name (char const *name)
{
- char const *base = name += FILESYSTEM_PREFIX_LEN (name);
- int all_slashes = 1;
+ char const *base = name + FILESYSTEM_PREFIX_LEN (name);
char const *p;
- for (p = name; *p; p++)
+ for (p = base; *p; p++)
{
if (ISSLASH (*p))
- base = p + 1;
- else
- all_slashes = 0;
- }
+ {
+ /* Treat multiple adjacent slashes like a single slash. */
+ do p++;
+ while (ISSLASH (*p));
- /* If NAME is all slashes, arrange to return `/'. */
- if (*base == '\0' && ISSLASH (*name) && all_slashes)
- --base;
+ /* If the file name ends in slash, use the trailing slash as
+ the basename if no non-slashes have been found. */
+ if (! *p)
+ {
+ if (ISSLASH (*base))
+ base = p - 1;
+ break;
+ }
- /* Make sure the last byte is not a slash. */
- assert (all_slashes || !ISSLASH (*(p - 1)));
+ /* *P is a non-slash preceded by a slash. */
+ base = p;
+ }
+ }
return (char *) base;
}
+
+/* Return the length of of the basename NAME. Typically NAME is the
+ value returned by base_name. Act like strlen (NAME), except omit
+ redundant trailing slashes. */
+
+size_t
+base_len (char const *name)
+{
+ size_t len;
+
+ for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
+ continue;
+
+ return len;
+}
/* dirname.c -- return all but the last element in a path
- Copyright (C) 1990, 1998, 2000 Free Software Foundation, Inc.
+ Copyright 1990, 1998, 2000, 2001 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
# include <config.h>
#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-#else
-char *malloc ();
-#endif
-#if defined STDC_HEADERS || defined HAVE_STRING_H
+#if STDC_HEADERS || HAVE_STRING_H
# include <string.h>
-#else
-# include <strings.h>
-# ifndef strrchr
-# define strrchr rindex
-# endif
-#endif
-#include <assert.h>
-
-#ifndef HAVE_DECL_MEMRCHR
-"this configure-time declaration test was not run"
-#endif
-#if !HAVE_DECL_MEMRCHR
-void *memrchr ();
#endif
#include "dirname.h"
+#include "xalloc.h"
-#ifndef FILESYSTEM_PREFIX_LEN
-# define FILESYSTEM_PREFIX_LEN(Filename) 0
-#endif
-
-#ifndef ISSLASH
-# define ISSLASH(C) ((C) == '/')
-#endif
-
-#define BACKSLASH_IS_PATH_SEPARATOR ISSLASH ('\\')
-
-/* Return the length of `dirname (PATH)' and set *RESULT to point
- to PATH or to `"."', as appropriate. Works properly even if
- there are trailing slashes (by effectively ignoring them).
- WARNING: This function doesn't work for cwd-relative names like
- `a:foo' that are specified with a drive-letter prefix. That case
- is handled in the caller. */
-static size_t
-dir_name_r (char const *path, char const **result)
+/* Return the length of `dirname (PATH)', or zero if PATH is
+ in the working directory. Works properly even if
+ there are trailing slashes (by effectively ignoring them). */
+size_t
+dir_len (char const *path)
{
- char const *slash;
- size_t length; /* Length of result, not including NUL. */
-
- slash = strrchr (path, '/');
- if (BACKSLASH_IS_PATH_SEPARATOR)
- {
- char const *b = strrchr (path, '\\');
- if (b && slash < b)
- slash = b;
- }
+ size_t prefix_length = FILESYSTEM_PREFIX_LEN (path);
+ size_t length;
- /* If the last byte of PATH is a slash, decrement SLASH until it's
- pointing at the leftmost in a sequence of trailing slashes. */
- if (slash && slash[1] == 0)
- {
- while (path < slash && ISSLASH (slash[-1]))
- {
- --slash;
- }
-
- if (path < slash)
- {
- size_t len = slash - path;
- slash = memrchr (path, '/', len);
- if (BACKSLASH_IS_PATH_SEPARATOR)
- {
- char const *b = memrchr (path, '\\', len);
- if (b && slash < b)
- slash = b;
- }
- }
- }
-
- if (slash == 0)
- {
- /* File is in the current directory. */
-
- length = FILESYSTEM_PREFIX_LEN (path);
-
- if (length == 0)
- {
- path = ".";
- length = 1;
- }
- }
- else
- {
- /* Remove any trailing slashes from the result. If we have a
- canonicalized "d:/path", leave alone the root case "d:/". */
- char const *lim = path + FILESYSTEM_PREFIX_LEN (path);
-
- while (lim < slash && ISSLASH (*slash))
- --slash;
+ /* Strip the basename and any redundant slashes before it. */
+ for (length = base_name (path) - path; prefix_length < length; length--)
+ if (! ISSLASH (path[length - 1]))
+ return length;
- length = slash - path + 1;
- }
-
- *result = path;
- return length;
+ /* But don't strip the only slash from "/". */
+ return prefix_length + ISSLASH (path[prefix_length]);
}
/* Return the leading directories part of PATH,
- allocated with malloc. If out of memory, return 0.
+ allocated with xmalloc.
Works properly even if there are trailing slashes
(by effectively ignoring them). */
char *
dir_name (char const *path)
{
- char const *result;
- size_t length = dir_name_r (path, &result);
- int append_dot = (length && length == FILESYSTEM_PREFIX_LEN (newpath));
- char *newpath = (char *) malloc (length + append_dot + 1);
- if (newpath == 0)
- return 0;
- strncpy (newpath, result, length);
- /* If PATH is "d:foo", return "d:.", the CWD on drive d: */
+ size_t length = dir_len (path);
+ int append_dot = (length == FILESYSTEM_PREFIX_LEN (path));
+ char *newpath = xmalloc (length + append_dot + 1);
+ memcpy (newpath, path, length);
if (append_dot)
newpath[length++] = '.';
newpath[length] = 0;
/*
Run the test like this (expect no output):
- gcc -DHAVE_CONFIG_H -DTEST_DIRNAME -I.. -O -Wall memrchr.c dirname.c
+ gcc -DHAVE_CONFIG_H -DTEST_DIRNAME -I.. -O -Wall \
+ basename.c dirname.c xmalloc.c
sed -n '/^BEGIN-DATA$/,/^END-DATA$/p' dirname.c|grep -v DATA|./a.out
BEGIN-DATA
# define MAX_BUFF_LEN 1024
# include <stdio.h>
-# include <stdlib.h>
int
main ()
if (strcmp (result, expected_result))
printf ("%s: got %s, expected %s\n", path, result, expected_result);
}
- exit (0);
-
+ return 0;
}
#endif
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2001 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
# endif
# endif
-char *
-dir_name PARAMS ((const char *path));
+# ifndef DIRECTORY_SEPARATOR
+# define DIRECTORY_SEPARATOR '/'
+# endif
+
+# ifndef ISSLASH
+# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
+# endif
+
+# ifndef FILESYSTEM_PREFIX_LEN
+# define FILESYSTEM_PREFIX_LEN(Filename) 0
+# endif
+
+char *base_name PARAMS ((char const *path));
+char *dir_name PARAMS ((char const *path));
+size_t base_len PARAMS ((char const *path));
+size_t dir_len PARAMS ((char const *path));
+
+int strip_trailing_slashes PARAMS ((char *path));
#endif /* not DIRNAME_H_ */
#include <assert.h>
#ifndef HAVE_DECL_FREE
-# error "this configure-time declaration test was not run"
+"this configure-time declaration test was not run"
#endif
#if !HAVE_DECL_FREE
void free ();
#endif
#ifndef HAVE_DECL_MALLOC
-# error "this configure-time declaration test was not run"
+"this configure-time declaration test was not run"
#endif
#if !HAVE_DECL_MALLOC
char *malloc ();
#include "hash.h"
+struct hash_table
+ {
+ /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1,
+ for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets
+ are not empty, there are N_ENTRIES active entries in the table. */
+ struct hash_entry *bucket;
+ struct hash_entry *bucket_limit;
+ unsigned n_buckets;
+ unsigned n_buckets_used;
+ unsigned n_entries;
+
+ /* Tuning arguments, kept in a physicaly separate structure. */
+ const Hash_tuning *tuning;
+
+ /* Three functions are given to `hash_initialize', see the documentation
+ block for this function. In a word, HASHER randomizes a user entry
+ into a number up from 0 up to some maximum minus 1; COMPARATOR returns
+ true if two user entries compare equally; and DATA_FREER is the cleanup
+ function for a user entry. */
+ Hash_hasher hasher;
+ Hash_comparator comparator;
+ Hash_data_freer data_freer;
+
+ /* A linked list of freed struct hash_entry structs. */
+ struct hash_entry *free_entry_list;
+
+#if USE_OBSTACK
+ /* Whenever obstacks are used, it is possible to allocate all overflowed
+ entries into a single stack, so they all can be freed in a single
+ operation. It is not clear if the speedup is worth the trouble. */
+ struct obstack entry_stack;
+#endif
+ };
+
/* A hash table contains many internal entries, each holding a pointer to
some user provided data (also called a user entry). An entry indistinctly
refers to both the internal entry and its associated user entry. A user
hash_clear (Hash_table *table)
{
struct hash_entry *bucket;
- struct hash_entry *cursor;
for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
{
if (bucket->data)
{
+ struct hash_entry *cursor;
+ struct hash_entry *next;
+
/* Free the bucket overflow. */
- for (cursor = bucket->next; cursor; cursor = cursor->next)
+ for (cursor = bucket->next; cursor; cursor = next)
{
if (table->data_freer)
(*table->data_freer) (cursor->data);
cursor->data = NULL;
+ next = cursor->next;
/* Relinking is done one entry at a time, as it is to be expected
that overflows are either rare or short. */
cursor->next = table->free_entry_list;
struct hash_entry *cursor;
if (bucket)
- printf ("%d:\n", slot);
+ printf ("%d:\n", bucket - table->bucket);
for (cursor = bucket; cursor; cursor = cursor->next)
{
char *s = (char *) cursor->data;
/* FIXME */
- printf (" %s\n", s);
+ if (s)
+ printf (" %s\n", s);
}
}
}
/* hash - hashing table processing.
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
Written by Jim Meyering <meyering@ascend.com>, 1998.
This program is free software; you can redistribute it and/or modify
/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use
obstacks instead of malloc, and recompile `hash.c' with same setting. */
-#ifndef PARAMS
-# if PROTOTYPES || __STDC__
-# define PARAMS(Args) Args
-# else
-# define PARAMS(Args) ()
+#ifndef HASH_H_
+# define HASH_H_
+
+# ifndef PARAMS
+# if PROTOTYPES || __STDC__
+# define PARAMS(Args) Args
+# else
+# define PARAMS(Args) ()
+# endif
# endif
-#endif
typedef unsigned (*Hash_hasher) PARAMS ((const void *, unsigned));
typedef bool (*Hash_comparator) PARAMS ((const void *, const void *));
typedef struct hash_tuning Hash_tuning;
-struct hash_table
- {
- /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1,
- for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets
- are not empty, there are N_ENTRIES active entries in the table. */
- struct hash_entry *bucket;
- struct hash_entry *bucket_limit;
- unsigned n_buckets;
- unsigned n_buckets_used;
- unsigned n_entries;
-
- /* Tuning arguments, kept in a physicaly separate structure. */
- const Hash_tuning *tuning;
-
- /* Three functions are given to `hash_initialize', see the documentation
- block for this function. In a word, HASHER randomizes a user entry
- into a number up from 0 up to some maximum minus 1; COMPARATOR returns
- true if two user entries compare equally; and DATA_FREER is the cleanup
- function for a user entry. */
- Hash_hasher hasher;
- Hash_comparator comparator;
- Hash_data_freer data_freer;
-
- /* A linked list of freed struct hash_entry structs. */
- struct hash_entry *free_entry_list;
-
-#if USE_OBSTACK
- /* Whenever obstacks are used, it is possible to allocate all overflowed
- entries into a single stack, so they all can be freed in a single
- operation. It is not clear if the speedup is worth the trouble. */
- struct obstack entry_stack;
-#endif
- };
+struct hash_table;
typedef struct hash_table Hash_table;
bool hash_rehash PARAMS ((Hash_table *, unsigned));
void *hash_insert PARAMS ((Hash_table *, const void *));
void *hash_delete PARAMS ((Hash_table *, const void *));
+
+#endif
/* Find the length of STRING, but scan at most MAXLEN characters.
- Copyright (C) 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 2000-2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- The GNU C 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 program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
- The GNU C Library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ 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 Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
# include <config.h>
# if !STDC_HEADERS && HAVE_MEMORY_H
# include <memory.h>
# endif
+/* Temporarily redefine strnlen so that an inconsistent prototype
+ (on at least AIX4.3.2.0 w/gcc-2.95.3) doesn't cause trouble. */
+# define strnlen system_strnlen
# include <string.h>
+# undef strnlen
#else
# include <strings.h>
#endif
/* xmalloc.c -- malloc with out of memory checking
- Copyright (C) 1990-1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1990-1999, 2000, 2002 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
# define EXIT_FAILURE 1
#endif
-#ifndef HAVE_DONE_WORKING_MALLOC_CHECK
-"you must run the autoconf test for a properly working malloc -- see malloc.m4"
+#ifndef HAVE_MALLOC
+"you must run the autoconf test for a properly working malloc"
#endif
-#ifndef HAVE_DONE_WORKING_REALLOC_CHECK
-"you must run the autoconf test for a properly working realloc --see realloc.m4"
+#ifndef HAVE_REALLOC
+"you must run the autoconf test for a properly working realloc"
#endif
/* Exit value when the requested amount of memory is not available.
-# serial 9
+# mbstate_t.m4 serial 9
+dnl Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License. As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
# From Paul Eggert.
# so you can't declare an object of that type.
# Check for this incompatibility with Standard C.
-# Include stdlib.h first, because otherwise this test would fail on Linux
-# (at least glibc-2.1.3) because the "_XOPEN_SOURCE 500" definition elicits
-# a syntax error in wchar.h due to the use of undefined __int32_t.
-
-AC_DEFUN([AC_MBSTATE_T],
- [
- AC_CHECK_HEADERS(stdlib.h)
-
- AC_CACHE_CHECK([for mbstate_t], ac_cv_type_mbstate_t,
- [AC_TRY_COMPILE([
-#if HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#include <wchar.h>],
- [mbstate_t x; return sizeof x;],
- ac_cv_type_mbstate_t=yes,
- ac_cv_type_mbstate_t=no)])
- if test $ac_cv_type_mbstate_t = no; then
- AC_DEFINE(mbstate_t, int,
+# AC_TYPE_MBSTATE_T
+# -----------------
+AC_DEFUN([AC_TYPE_MBSTATE_T],
+ [AC_CACHE_CHECK([for mbstate_t], ac_cv_type_mbstate_t,
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [AC_INCLUDES_DEFAULT
+# include <wchar.h>],
+ [mbstate_t x; return sizeof x;])],
+ [ac_cv_type_mbstate_t=yes],
+ [ac_cv_type_mbstate_t=no])])
+ if test $ac_cv_type_mbstate_t = yes; then
+ AC_DEFINE([HAVE_MBSTATE_T], 1,
+ [Define to 1 if <wchar.h> declares mbstate_t.])
+ else
+ AC_DEFINE([mbstate_t], int,
[Define to a type if <wchar.h> does not define.])
fi])