From eb9568566a284c28cb45bc7c832a08155d6c08bd Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 12 Aug 2002 14:25:24 +0000 Subject: [PATCH] Sync with fileutils. --- lib/argmatch.h | 6 +-- lib/basename.c | 72 ++++++++++++++------------ lib/dirname.c | 132 +++++++++--------------------------------------- lib/dirname.h | 22 ++++++-- lib/hash.c | 50 +++++++++++++++--- lib/hash.h | 53 +++++-------------- lib/strnlen.c | 27 +++++----- lib/xmalloc.c | 10 ++-- m4/mbstate_t.m4 | 43 ++++++++-------- 9 files changed, 186 insertions(+), 229 deletions(-) diff --git a/lib/argmatch.h b/lib/argmatch.h index dd2a6556..b7193009 100644 --- a/lib/argmatch.h +++ b/lib/argmatch.h @@ -1,5 +1,5 @@ /* 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 @@ -104,7 +104,7 @@ int __xargmatch_internal /* 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)), \ @@ -123,7 +123,7 @@ const char *argmatch_to_argument 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_ */ diff --git a/lib/basename.c b/lib/basename.c index 36e0f62b..54f037ed 100644 --- a/lib/basename.c +++ b/lib/basename.c @@ -19,53 +19,61 @@ # include #endif -#include -#include - -#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 #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; +} diff --git a/lib/dirname.c b/lib/dirname.c index 94f8c893..9fb5f093 100644 --- a/lib/dirname.c +++ b/lib/dirname.c @@ -1,5 +1,5 @@ /* 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 @@ -19,126 +19,43 @@ # include #endif -#ifdef STDC_HEADERS -# include -#else -char *malloc (); -#endif -#if defined STDC_HEADERS || defined HAVE_STRING_H +#if STDC_HEADERS || HAVE_STRING_H # include -#else -# include -# ifndef strrchr -# define strrchr rindex -# endif -#endif -#include - -#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; @@ -149,7 +66,8 @@ dir_name (char const *path) /* 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 @@ -165,7 +83,6 @@ END-DATA # define MAX_BUFF_LEN 1024 # include -# include int main () @@ -183,7 +100,6 @@ main () if (strcmp (result, expected_result)) printf ("%s: got %s, expected %s\n", path, result, expected_result); } - exit (0); - + return 0; } #endif diff --git a/lib/dirname.h b/lib/dirname.h index fc466996..cea14c04 100644 --- a/lib/dirname.h +++ b/lib/dirname.h @@ -1,4 +1,4 @@ -/* 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 @@ -25,7 +25,23 @@ # 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_ */ diff --git a/lib/hash.c b/lib/hash.c index da73d156..df8f4bd6 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -36,14 +36,14 @@ typedef enum {false = 0, true = 1} bool; #include #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 (); @@ -61,6 +61,40 @@ 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 @@ -576,19 +610,22 @@ void 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; @@ -995,13 +1032,14 @@ hash_print (const Hash_table *table) 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); } } } diff --git a/lib/hash.h b/lib/hash.h index 27b6fa45..a9fc1876 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -1,5 +1,5 @@ /* 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 , 1998. This program is free software; you can redistribute it and/or modify @@ -21,13 +21,16 @@ /* 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 *)); @@ -54,39 +57,7 @@ struct hash_tuning 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; @@ -118,3 +89,5 @@ void hash_free PARAMS ((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 diff --git a/lib/strnlen.c b/lib/strnlen.c index 15b65d84..43047d94 100644 --- a/lib/strnlen.c +++ b/lib/strnlen.c @@ -1,21 +1,20 @@ /* 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 @@ -25,7 +24,11 @@ # if !STDC_HEADERS && HAVE_MEMORY_H # include # 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 +# undef strnlen #else # include #endif diff --git a/lib/xmalloc.c b/lib/xmalloc.c index 2f103d60..bc6c0bd1 100644 --- a/lib/xmalloc.c +++ b/lib/xmalloc.c @@ -1,5 +1,5 @@ /* 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 @@ -46,12 +46,12 @@ void free (); # 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. diff --git a/m4/mbstate_t.m4 b/m4/mbstate_t.m4 index ae2bcf1e..a07f51bc 100644 --- a/m4/mbstate_t.m4 +++ b/m4/mbstate_t.m4 @@ -1,4 +1,10 @@ -# 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. @@ -6,24 +12,21 @@ # 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 -#endif -#include ], - [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 ], + [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 declares mbstate_t.]) + else + AC_DEFINE([mbstate_t], int, [Define to a type if does not define.]) fi]) -- 2.45.2