Mercurial > hg > octave-kai > gnulib-hg
changeset 5126:cc8fdf2939bf
(mempcpy): Don't define if a system header defines it.
Don't include stdio.h, stdlib.h, unistd.h, strdup.h.
(longest_relative_suffix): New function.
(path_concat): Use it. Assume first argument is not NULL.
Port to DOS. Omit redundant separators.
Report an error instead of returning NULL.
Use mempcpy instead of memcpy.
(xpath_concat): Remove: not declared or used.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Fri, 06 Aug 2004 04:48:31 +0000 |
parents | 774b11465125 |
children | 3ab3f8e5b342 |
files | lib/path-concat.c |
diffstat | 1 files changed, 37 insertions(+), 60 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/path-concat.c +++ b/lib/path-concat.c @@ -26,85 +26,62 @@ /* Specification. */ #include "path-concat.h" -#ifndef HAVE_MEMPCPY +#include <string.h> + +#include "dirname.h" +#include "xalloc.h" + +#if ! HAVE_MEMPCPY && ! defined mempcpy # define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) #endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if HAVE_UNISTD_H -# include <unistd.h> -#endif +/* Return the longest suffix of F that is a relative file name. + If it has no such suffix, return the empty string. */ -#include "strdup.h" -#include "dirname.h" -#include "xalloc.h" +static char const * +longest_relative_suffix (char const *f) +{ + for (f += FILE_SYSTEM_PREFIX_LEN (f); ISSLASH (*f); f++) + continue; + return f; +} -/* Concatenate two pathname components, DIR and BASE, in - newly-allocated storage and return the result. Return 0 if out of - memory. Add a slash between DIR and BASE in the result if neither - would contribute one. If each would contribute at least one, elide - one from the end of DIR. Otherwise, simply concatenate DIR and - BASE. In any case, if BASE_IN_RESULT is non-NULL, set +/* Concatenate two pathname components, DIR and ABASE, in + newly-allocated storage and return the result. + The resulting file name F is such that the commands "ls F" and "(cd + DIR; ls BASE)" refer to the same file, where BASE is ABASE with any + file system prefixes and leading separators removed. + Arrange for a directory separator if necessary between DIR and BASE + in the result, removing any redundant separators. + In any case, if BASE_IN_RESULT is non-NULL, set *BASE_IN_RESULT to point to the copy of BASE in the returned concatenation. - DIR may be NULL, BASE must not be. - - Return NULL if memory is exhausted. */ + Report an error if memory is exhausted. */ char * -path_concat (const char *dir, const char *base, char **base_in_result) +path_concat (char const *dir, char const *abase, char **base_in_result) { - char *p; - char *p_concat; - size_t baselen; - size_t dirlen; + char const *dirbase = base_name (dir); + size_t dirbaselen = base_len (dirbase); + size_t dirlen = dirbase - dir + dirbaselen; + size_t needs_separator = (dirbaselen && ! ISSLASH (dirbase[dirbaselen - 1])); - if (!dir) - { - p_concat = strdup (base); - if (base_in_result) - *base_in_result = p_concat; - return p_concat; - } + char const *base = longest_relative_suffix (abase); + size_t baselen = strlen (base); - /* DIR is not empty. */ - baselen = base_len (base); - dirlen = strlen (dir); - - p_concat = malloc (dirlen + baselen + 2); - if (!p_concat) - return 0; + char *p_concat = xmalloc (dirlen + needs_separator + baselen + 1); + char *p; p = mempcpy (p_concat, dir, dirlen); - - if (FILESYSTEM_PREFIX_LEN (dir) < dirlen) - { - if (ISSLASH (*(p - 1)) && ISSLASH (*base)) - --p; - else if (!ISSLASH (*(p - 1)) && !ISSLASH (*base)) - *p++ = DIRECTORY_SEPARATOR; - } + *p = DIRECTORY_SEPARATOR; + p += needs_separator; if (base_in_result) *base_in_result = p; - memcpy (p, base, baselen); - p[baselen] = '\0'; + p = mempcpy (p, base, baselen); + *p = '\0'; return p_concat; } - -/* Same, but die when memory is exhausted. */ - -char * -xpath_concat (const char *dir, const char *base, char **base_in_result) -{ - char *res = path_concat (dir, base, base_in_result); - if (! res) - xalloc_die (); - return res; -}