https://gcc.gnu.org/g:31dd621796f9ff30b3df129a0e47c8d2348fa8c3
commit r15-8249-g31dd621796f9ff30b3df129a0e47c8d2348fa8c3 Author: Jose E. Marchesi <jose.march...@oracle.com> Date: Mon Mar 17 12:47:40 2025 +0100 libiberty: add ldirname function This patch adds a function ldirname to libiberty. It is implemented in terms of lbasename. Basically, given a given pathname, the dirname part is what is not the basename minus the last directory separator separating the dirname with the basename. include/ChangeLog * libiberty.h (ldirname): New function declaration. (dos_ldirname): Likewise. (unix_ldirname): Likewise. libiberty/ChangeLog * ldirname.c: New file. * Makefile.in (CFILES): Add ldirname.c. (REQUIRED_OFILES): Add ldirname.$(objext). (./ldirname.$(objext)): New rule. * makefile.vms (OBJS): Add ldirname.obj. * configure.com (FILES): Add ldirname. Diff: --- include/libiberty.h | 12 +++++++ libiberty/Makefile.in | 14 +++++++- libiberty/configure.com | 2 +- libiberty/ldirname.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ libiberty/makefile.vms | 2 +- 5 files changed, 121 insertions(+), 3 deletions(-) diff --git a/include/libiberty.h b/include/libiberty.h index 9cd1de4684cd..f2e763a306a1 100644 --- a/include/libiberty.h +++ b/include/libiberty.h @@ -133,6 +133,18 @@ extern const char *dos_lbasename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIB extern const char *unix_lbasename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); +/* A dirname () that is always compiled in. */ + +extern char *ldirname (const char *) ATTRIBUTE_NONNULL(1); + +/* Same, but assumes DOS semantics regardless of host. */ + +extern char *dos_ldirname (const char *) ATTRIBUTE_NONNULL(1); + +/* Same, but assumes Unix semantics regardless of host. */ + +extern char *unix_ldirname (const char *) ATTRIBUTE_NONNULL(1); + /* A well-defined realpath () that is always compiled in. */ extern char *lrealpath (const char *); diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 0db124338af1..4870fa95f2f3 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -136,6 +136,7 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \ hashtab.c hex.c \ index.c insque.c \ lbasename.c \ + ldirname.c \ lrealpath.c \ make-relative-prefix.c \ make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmem.c \ @@ -179,7 +180,7 @@ REQUIRED_OFILES = \ ./fnmatch.$(objext) ./fopen_unlocked.$(objext) \ ./getopt.$(objext) ./getopt1.$(objext) ./getpwd.$(objext) \ ./getruntime.$(objext) ./hashtab.$(objext) ./hex.$(objext) \ - ./lbasename.$(objext) ./lrealpath.$(objext) \ + ./lbasename.$(objext) ./ldirname.$(objext) ./lrealpath.$(objext)\ ./make-relative-prefix.$(objext) ./make-temp-file.$(objext) \ ./objalloc.$(objext) \ ./obstack.$(objext) \ @@ -965,6 +966,17 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir else true; fi $(COMPILE.c) $(srcdir)/lbasename.c $(OUTPUT_OPTION) +./ldirname.$(objext): $(srcdir)/ldirname.c config.h $(INCDIR)/ansidecl.h \ + $(INCDIR)/filenames.h $(INCDIR)/hashtab.h $(INCDIR)/libiberty.h \ + $(INCDIR)/safe-ctype.h + if [ x"$(PICFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(srcdir)/ldirname.c -o pic/$@; \ + else true; fi + if [ x"$(NOASANFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/ldirname.c -o noasan/$@; \ + else true; fi + $(COMPILE.c) $(srcdir)/ldirname.c $(OUTPUT_OPTION) + ./lrealpath.$(objext): $(srcdir)/lrealpath.c config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/libiberty.h if [ x"$(PICFLAG)" != x ]; then \ diff --git a/libiberty/configure.com b/libiberty/configure.com index 030182914f74..55aee2f78f98 100644 --- a/libiberty/configure.com +++ b/libiberty/configure.com @@ -17,7 +17,7 @@ $DECK $ FILES="getopt,obstack,xexit,xmalloc,hex,getopt1,cplus-dem,cp-demangle,"+- "cp-demint,asprintf,vasprintf,mkstemps,concat,getruntime,getpagesize,"+- "getpwd,xstrerror,xmemdup,xstrdup,xatexit,choose-temp,fnmatch,objalloc,"+- - "safe-ctype,hashtab,lbasename,argv,lrealpath,make-temp-file,"+- + "safe-ctype,hashtab,lbasename,ldirname,argv,lrealpath,make-temp-file,"+- "stpcpy,unlink-if-ordinary" $ OPT="/noopt/debug/warnings=disable=(missingreturn)" $ CFLAGS=OPT + "/include=([],[-.include])/name=(as_is,shortened)" +- diff --git a/libiberty/ldirname.c b/libiberty/ldirname.c new file mode 100644 index 000000000000..e3cd5c816c1b --- /dev/null +++ b/libiberty/ldirname.c @@ -0,0 +1,94 @@ +/* Libiberty dirname. Like dirname, but is not overridden by the + system C library. + Copyright (C) 2025 Free Software Foundation, Inc. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +/* + +@deftypefn Replacement {char*} ldirname (const char *@var{name}) + +Given a pointer to a string containing a typical pathname +(@samp{/usr/src/cmd/ls/ls.c} for example), returns a string containing the +passed string up to, but not including, the final directory separator. + +If the given pathname doesn't contain a directory separator then this funtion +returns the empty string; this includes an empty given pathname. @code{NULL} +is returned on memory allocation error. + +@end deftypefn + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "ansidecl.h" +#include "libiberty.h" +#include "safe-ctype.h" +#include "filenames.h" + +/* For malloc. */ +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +/* For memcpy. */ +# if HAVE_STRING_H +# include <string.h> +# else +# if HAVE_STRINGS_H +# include <strings.h> +# endif +# endif + +#define LDIRNAME(FPREFIX,DIRSEP) \ + char *FPREFIX##_ldirname (const char *name) \ + { \ + /* Note that lbasename guarantees that the returned */ \ + /* pointer lies within the passed string. */ \ + const char *basename = FPREFIX##_lbasename (name); \ + size_t size = basename - name; \ + char *res = NULL; \ + \ + res = (char*) malloc (size + 1); \ + if (res != NULL) \ + { \ + if (size > 0) \ + { \ + if (IS_DIR_SEPARATOR_1 ((DIRSEP),name[size - 1])) \ + size -= 1; \ + memcpy (res, name, size); \ + } \ + res[size] = '\0'; \ + } \ + \ + return res; \ + } + +LDIRNAME(dos,1) +LDIRNAME(unix,0) + +char * +ldirname (const char *name) +{ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + return dos_ldirname (name); +#else + return unix_ldirname (name); +#endif +} diff --git a/libiberty/makefile.vms b/libiberty/makefile.vms index 15a7d0a206b6..4cfcc986f666 100644 --- a/libiberty/makefile.vms +++ b/libiberty/makefile.vms @@ -12,7 +12,7 @@ OBJS=getopt.obj,obstack.obj,xexit.obj,xmalloc.obj,hex.obj,\ asprintf.obj vasprintf.obj,mkstemps.obj,filename_cmp.obj,\ concat.obj,getruntime.obj,getpagesize.obj,getpwd.obj,xstrerror.obj,\ xmemdup.obj,xstrdup.obj,xatexit.obj,choose-temp.obj,fnmatch.obj,\ - objalloc.obj,safe-ctype.obj,hashtab.obj,lbasename.obj,argv.obj,\ + objalloc.obj,safe-ctype.obj,hashtab.obj,lbasename.obj,ldirname.obj,argv.obj,\ lrealpath.obj,make-temp-file.obj,stpcpy.obj,unlink-if-ordinary.obj,\ dwarfnames.obj