basename and dirname (was Re: CVS mess)



Mark Galassi <rosalia@cygnus.com> writes:
> > df.o: In function `find_mount_point':
> > /usr/local/src/redhat/SOURCES/gnome-utils/gdiskfree/df.c:511: undefined
> > reference to `dirname'
> 
>     Jarl> i know Gnome is alpha, but errors like these can be avoided,
>     Jarl> to my humble opinion....
> 
> I worked on that one for a while.  I finally just put in what you see
> below.  I have no idea if it works, since I don't know what the spec
> for dirname is.
> 
> /* hmm: for some reason this function is used here but not at all
>    available on my redhat 4.2 system */
> static char *dirname(char *tmp)
> {
>   return g_strdup(strrchr(tmp, '/')); /* I think it's this easy */
> }

This looks more like a `basename'-like algorithm to me.

> I also added the g_strdup() just in case, since I see that the
> invocation is
> 
>       dir = dirname (tmp);
>       free (tmp);
>       rv = chdir (dir);
>       free (dir);
>
> so tmp is freed before dir is used, which means that dirname() must
> create new storage. 

I checked the `fileutils' source.  `fileutils' doesn't use the `dirname'
that comes with the OS -- it is always linked against an internal
version.  Similarly for `basename'.  This is probably since different
m/cs have different semantics.  On some m/cs, dirname/basename appear to
be destructive -- and don't use malloc for the return val.  For eg., the
above fragment is dangerous when linked against Solaris or `glibc' (as
it currently is).

On the whole, `dirname' and `basename' seem to a big mess -- with
different usages all over the place.  `glibc' itself provides two
behaviours for `basename' depending on whether you include <libgen.h> or
not, yuck.

It appears that we would be much better off defining our own `g_dirname'
and `g_basename' and use those exclusively.  In fact, GNU fileutils takes
this route in `basename.c' (the function is called `base_name'):

  /* 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.  */

My take on this whole deal:

* Put g_dirname and g_basename into `glib' or somewhere nice.  If
  nothing else, we could put `g_dirname' into gnome-utils/gdiskfree/df.c
  and `g_basename' somewhere in ORBit.

* Anyway, `g_basename' would be non-destructive.  `g_dirname' would use
  `g_malloc' to allocate its return value.

* Modify ORBit and gnome-utils/gdiskfree to use the g_* versions.
  (Yay, no libiberty ;-)  We would then know what exactly we are getting
  with these functions.

- Hari
-- 
Raja R Harinath ------------------------------ harinath@cs.umn.edu
"When all else fails, read the instructions."      -- Cahn's Axiom
"Our policy is, when in doubt, do the right thing."   -- Roy L Ash



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]