summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2021-07-25 08:00:50 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2021-07-25 08:00:50 +0200
commitaa9cba658768aba4da1b74ffb33d9962ffff5756 (patch)
tree39d07450a850e5b46687f18c367e64e723cbb7a3 /src
parent03f844249cb15a8380d09041a537803c933a2769 (diff)
downloademacs-aa9cba658768aba4da1b74ffb33d9962ffff5756.tar.gz
Allow empty elements in directory-append
* doc/lispref/files.texi (Directory Names): Document it. * src/fileio.c (Fdirectory_append): Allow empty elements.
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/src/fileio.c b/src/fileio.c
index d6b3e7bca40..3d8b082a59c 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -751,14 +751,14 @@ For that reason, you should normally use `make-temp-file' instead. */)
DEFUN ("directory-append", Fdirectory_append, Sdirectory_append, 1, MANY, 0,
doc: /* Append COMPONENTS to DIRECTORY and return the resulting string.
-COMPONENTS must be strings.
+Elements in COMPONENTS must be a string or nil.
DIRECTORY or the non-final elements in COMPONENTS may or may not end
with a slash -- if they don't end with a slash, a slash will be
inserted before contatenating.
usage: (record DIRECTORY &rest COMPONENTS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
- ptrdiff_t chars = 0, bytes = 0, multibytes = 0;
+ ptrdiff_t chars = 0, bytes = 0, multibytes = 0, eargs = 0;
Lisp_Object *elements = args;
Lisp_Object result;
ptrdiff_t i;
@@ -768,9 +768,13 @@ usage: (record DIRECTORY &rest COMPONENTS) */)
for (i = 0; i < nargs; i++)
{
Lisp_Object arg = args[i];
+ /* Skip empty and nil elements. */
+ if (NILP (arg))
+ continue;
CHECK_STRING (arg);
if (SCHARS (arg) == 0)
- xsignal1 (Qfile_error, build_string ("Empty file name"));
+ continue;
+ eargs++;
/* Multibyte and non-ASCII. */
if (STRING_MULTIBYTE (arg) && SCHARS (arg) != SBYTES (arg))
multibytes++;
@@ -789,25 +793,41 @@ usage: (record DIRECTORY &rest COMPONENTS) */)
}
/* Convert if needed. */
- if (multibytes != 0 && multibytes != nargs)
+ if ((multibytes != 0 && multibytes != nargs)
+ || eargs != nargs)
{
- elements = xmalloc (nargs * sizeof *elements);
+ int j = 0;
+ elements = xmalloc (eargs * sizeof *elements);
bytes = 0;
+ chars = 0;
+
+ /* Filter out nil/"". */
for (i = 0; i < nargs; i++)
{
Lisp_Object arg = args[i];
+ if (!NILP (arg) && SCHARS (arg) != 0)
+ elements[j++] = arg;
+ }
+
+ for (i = 0; i < eargs; i++)
+ {
+ Lisp_Object arg = elements[i];
/* Use multibyte or all-ASCII strings as is. */
- if (STRING_MULTIBYTE (arg) || string_ascii_p (arg))
- elements[i] = arg;
- else
+ if (!STRING_MULTIBYTE (arg) && !string_ascii_p (arg))
elements[i] = Fstring_to_multibyte (arg);
arg = elements[i];
/* We have to recompute the number of bytes. */
- if (i == nargs - 1
+ if (i == eargs - 1
|| IS_DIRECTORY_SEP (*(SSDATA (arg) + SBYTES (arg) - 1)))
- bytes += SBYTES (arg);
+ {
+ bytes += SBYTES (arg);
+ chars += SCHARS (arg);
+ }
else
- bytes += SBYTES (arg) + 1;
+ {
+ bytes += SBYTES (arg) + 1;
+ chars += SCHARS (arg) + 1;
+ }
}
}
@@ -821,13 +841,13 @@ usage: (record DIRECTORY &rest COMPONENTS) */)
/* Copy over the data. */
char *p = SSDATA (result);
- for (i = 0; i < nargs; i++)
+ for (i = 0; i < eargs; i++)
{
Lisp_Object arg = elements[i];
memcpy (p, SSDATA (arg), SBYTES (arg));
p += SBYTES (arg);
/* The last element shouldn't have a slash added at the end. */
- if (i < nargs - 1 && !IS_DIRECTORY_SEP (*(p - 1)))
+ if (i < eargs - 1 && !IS_DIRECTORY_SEP (*(p - 1)))
*p++ = DIRECTORY_SEP;
}