diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 8 | ||||
-rw-r--r-- | lib/Makefile.in | 32 | ||||
-rw-r--r-- | lib/basename.c | 79 | ||||
-rw-r--r-- | lib/dirname.c | 121 | ||||
-rw-r--r-- | lib/dirname.h | 47 | ||||
-rw-r--r-- | lib/stripslash.c | 40 |
6 files changed, 312 insertions, 15 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index e04136e..4ab24b9 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -8,7 +8,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --aux-dir=. --macro-prefix=gl alloca alloca-opt atexit closeout error exclude exit exitfail extensions fnmatch fnmatch-gnu fpending getcwd getopt gettext gettext-h havelib inttostr lstat malloc mbchar mbuiter memchr memcpy mempcpy memset obstack pathmax quotearg realloc regex restrict stat-macros stdbool strcase strcspn strdup strnlen1 strpbrk strsep strstr xalloc xalloc-die xgetcwd +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --aux-dir=. --macro-prefix=gl alloca alloca-opt atexit closeout dirname error exclude exit exitfail extensions fnmatch fnmatch-gnu fpending getcwd getopt gettext gettext-h havelib inttostr lstat malloc mbchar mbuiter memchr memcpy mempcpy memset obstack pathmax quotearg realloc regex restrict stat-macros stdbool strcase strcspn strdup strnlen1 strpbrk strsep strstr xalloc xalloc-die xgetcwd AUTOMAKE_OPTIONS = 1.5 gnits no-dependencies @@ -44,6 +44,12 @@ MOSTLYCLEANFILES += alloca.h alloca.h-t ## end gnulib module alloca-opt +## begin gnulib module dirname + +libgnu_a_SOURCES += basename.c stripslash.c + +## end gnulib module dirname + ## begin gnulib module exit libgnu_a_SOURCES += exit.h diff --git a/lib/Makefile.in b/lib/Makefile.in index 19e3585..242b7c3 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -23,7 +23,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --aux-dir=. --macro-prefix=gl alloca alloca-opt atexit closeout error exclude exit exitfail extensions fnmatch fnmatch-gnu fpending getcwd getopt gettext gettext-h havelib inttostr lstat malloc mbchar mbuiter memchr memcpy mempcpy memset obstack pathmax quotearg realloc regex restrict stat-macros stdbool strcase strcspn strdup strnlen1 strpbrk strsep strstr xalloc xalloc-die xgetcwd +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --aux-dir=. --macro-prefix=gl alloca alloca-opt atexit closeout dirname error exclude exit exitfail extensions fnmatch fnmatch-gnu fpending getcwd getopt gettext gettext-h havelib inttostr lstat malloc mbchar mbuiter memchr memcpy mempcpy memset obstack pathmax quotearg realloc regex restrict stat-macros stdbool strcase strcspn strdup strnlen1 strpbrk strsep strstr xalloc xalloc-die xgetcwd SOURCES = $(libgnu_a_SOURCES) @@ -51,20 +51,22 @@ build_triplet = @build@ host_triplet = @host@ subdir = lib DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in __fpending.c \ - __fpending.h alloca.c atexit.c closeout.c closeout.h error.c \ - error.h exclude.c exclude.h exitfail.c exitfail.h fnmatch.c \ - getcwd.c getcwd.h getopt.c getopt1.c imaxtostr.c intprops.h \ - inttostr.c inttostr.h lstat.c lstat.h malloc.c mbchar.c \ - memchr.c memcpy.c mempcpy.c mempcpy.h memset.c obstack.c \ - obstack.h offtostr.c pathmax.h quotearg.c quotearg.h realloc.c \ - regcomp.c regex.c regex.h regex_internal.c regex_internal.h \ - regexec.c stat-macros.h strcasecmp.c strcspn.c strdup.c \ - strdup.h strncasecmp.c strpbrk.c strsep.c strstr.c umaxtostr.c \ - xalloc.h xgetcwd.c xgetcwd.h xmalloc.c + __fpending.h alloca.c atexit.c closeout.c closeout.h dirname.c \ + dirname.h error.c error.h exclude.c exclude.h exitfail.c \ + exitfail.h fnmatch.c getcwd.c getcwd.h getopt.c getopt1.c \ + imaxtostr.c intprops.h inttostr.c inttostr.h lstat.c lstat.h \ + malloc.c mbchar.c memchr.c memcpy.c mempcpy.c mempcpy.h \ + memset.c obstack.c obstack.h offtostr.c pathmax.h quotearg.c \ + quotearg.h realloc.c regcomp.c regex.c regex.h \ + regex_internal.c regex_internal.h regexec.c stat-macros.h \ + strcasecmp.c strcspn.c strdup.c strdup.h strncasecmp.c \ + strpbrk.c strsep.c strstr.c umaxtostr.c xalloc.h xgetcwd.c \ + xgetcwd.h xmalloc.c ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/alloca.m4 \ $(top_srcdir)/m4/atexit.m4 $(top_srcdir)/m4/closeout.m4 \ $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/d-ino.m4 \ + $(top_srcdir)/m4/dirname.m4 $(top_srcdir)/m4/dos.m4 \ $(top_srcdir)/m4/error.m4 $(top_srcdir)/m4/exclude.m4 \ $(top_srcdir)/m4/exitfail.m4 $(top_srcdir)/m4/extensions.m4 \ $(top_srcdir)/m4/fnmatch.m4 $(top_srcdir)/m4/fpending.m4 \ @@ -108,7 +110,8 @@ AR = ar ARFLAGS = cru libgnu_a_AR = $(AR) $(ARFLAGS) libgnu_a_DEPENDENCIES = @LIBOBJS@ @ALLOCA@ -am_libgnu_a_OBJECTS = strnlen1.$(OBJEXT) xalloc-die.$(OBJEXT) +am_libgnu_a_OBJECTS = basename.$(OBJEXT) stripslash.$(OBJEXT) \ + strnlen1.$(OBJEXT) xalloc-die.$(OBJEXT) libgnu_a_OBJECTS = $(am_libgnu_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = @@ -246,8 +249,9 @@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = 1.5 gnits no-dependencies noinst_LIBRARIES = libgnu.a -libgnu_a_SOURCES = exit.h gettext.h mbchar.h mbuiter.h strcase.h \ - strnlen1.h strnlen1.c strpbrk.h strsep.h strstr.h xalloc-die.c +libgnu_a_SOURCES = basename.c stripslash.c exit.h gettext.h mbchar.h \ + mbuiter.h strcase.h strnlen1.h strnlen1.c strpbrk.h strsep.h \ + strstr.h xalloc-die.c libgnu_a_LIBADD = @LIBOBJS@ @ALLOCA@ EXTRA_DIST = alloca_.h fnmatch_.h fnmatch_loop.c getopt_.h \ getopt_int.h inttostr.c stdbool_.h diff --git a/lib/basename.c b/lib/basename.c new file mode 100644 index 0000000..5cc97cd --- /dev/null +++ b/lib/basename.c @@ -0,0 +1,79 @@ +/* basename.c -- return the last element in a file name + + Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005 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 + the Free Software Foundation; either version 2, or (at your option) + any later version. + + 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 General Public License for more details. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "dirname.h" +#include <string.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. + + 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 + FILE_SYSTEM_PREFIX_LEN (name); + char const *p; + + for (p = base; *p; p++) + { + if (ISSLASH (*p)) + { + /* Treat multiple adjacent slashes like a single slash. */ + do p++; + while (ISSLASH (*p)); + + /* 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; + } + + /* *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 new file mode 100644 index 0000000..e2b9d64 --- /dev/null +++ b/lib/dirname.c @@ -0,0 +1,121 @@ +/* dirname.c -- return all but the last element in a file name + + Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005 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 + the Free Software Foundation; either version 2, or (at your option) + any later version. + + 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 General Public License for more details. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "dirname.h" + +#include <string.h> +#include "xalloc.h" + +/* Return the length of `dirname (FILE)', or zero if FILE is + in the working directory. Works properly even if + there are trailing slashes (by effectively ignoring them). */ +size_t +dir_len (char const *file) +{ + size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file); + size_t length; + + /* Strip the basename and any redundant slashes before it. */ + for (length = base_name (file) - file; prefix_length < length; length--) + if (! ISSLASH (file[length - 1])) + return length; + + /* But don't strip the only slash from "/". */ + return prefix_length + ISSLASH (file[prefix_length]); +} + +/* Return the leading directories part of FILE, + allocated with xmalloc. + Works properly even if there are trailing slashes + (by effectively ignoring them). */ + +char * +dir_name (char const *file) +{ + size_t length = dir_len (file); + bool append_dot = (length == FILE_SYSTEM_PREFIX_LEN (file)); + char *dir = xmalloc (length + append_dot + 1); + memcpy (dir, file, length); + if (append_dot) + dir[length++] = '.'; + dir[length] = 0; + return dir; +} + +#ifdef TEST_DIRNAME +/* + +Run the test like this (expect no output): + gcc -DHAVE_CONFIG_H -DTEST_DIRNAME -I.. -O -Wall \ + basename.c dirname.c xmalloc.c error.c + sed -n '/^BEGIN-DATA$/,/^END-DATA$/p' dirname.c|grep -v DATA|./a.out + +If it's been built on a DOS or Windows platforms, run another test like +this (again, expect no output): + sed -n '/^BEGIN-DOS-DATA$/,/^END-DOS-DATA$/p' dirname.c|grep -v DATA|./a.out + +BEGIN-DATA +foo//// . +bar/foo//// bar +foo/ . +/ / +. . +a . +END-DATA + +BEGIN-DOS-DATA +c:///// c:/ +c:/ c:/ +c:/. c:/ +c:foo c:. +c:foo/bar c:foo +END-DOS-DATA + +*/ + +# define MAX_BUFF_LEN 1024 +# include <stdio.h> + +char *program_name; + +int +main (int argc, char *argv[]) +{ + char buff[MAX_BUFF_LEN + 1]; + + program_name = argv[0]; + + buff[MAX_BUFF_LEN] = 0; + while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0]) + { + char file[MAX_BUFF_LEN]; + char expected_result[MAX_BUFF_LEN]; + char const *result; + sscanf (buff, "%s %s", file, expected_result); + result = dir_name (file); + if (strcmp (result, expected_result)) + printf ("%s: got %s, expected %s\n", file, result, expected_result); + } + return 0; +} +#endif diff --git a/lib/dirname.h b/lib/dirname.h new file mode 100644 index 0000000..1688ae8 --- /dev/null +++ b/lib/dirname.h @@ -0,0 +1,47 @@ +/* Take file names apart into directory and base names. + + Copyright (C) 1998, 2001, 2003, 2004, 2005 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 + the Free Software Foundation; either version 2, or (at your option) + any later version. + + 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 General Public License for more details. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef DIRNAME_H_ +# define DIRNAME_H_ 1 + +# include <stdbool.h> +# include <stddef.h> + +# ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +# endif + +# ifndef ISSLASH +# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +# endif + +# ifndef FILE_SYSTEM_PREFIX_LEN +# define FILE_SYSTEM_PREFIX_LEN(File_name) 0 +# endif + +# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) +# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) + +char *base_name (char const *file); +char *dir_name (char const *file); +size_t base_len (char const *file); +size_t dir_len (char const *file); + +bool strip_trailing_slashes (char *file); + +#endif /* not DIRNAME_H_ */ diff --git a/lib/stripslash.c b/lib/stripslash.c new file mode 100644 index 0000000..9b55da4 --- /dev/null +++ b/lib/stripslash.c @@ -0,0 +1,40 @@ +/* stripslash.c -- remove redundant trailing slashes from a file name + + Copyright (C) 1990, 2001, 2003, 2004, 2005 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 + the Free Software Foundation; either version 2, or (at your option) + any later version. + + 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 General Public License for more details. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "dirname.h" + +/* Remove trailing slashes from FILE. + Return true if a trailing slash was removed. + This is useful when using file name completion from a shell that + adds a "/" after directory names (such as tcsh and bash), because + the Unix rename and rmdir system calls return an "Invalid argument" error + when given a file that ends in "/" (except for the root directory). */ + +bool +strip_trailing_slashes (char *file) +{ + char *base = base_name (file); + char *base_lim = base + base_len (base); + bool had_slash = (*base_lim != '\0'); + *base_lim = '\0'; + return had_slash; +} |