Skip to content

Commit 5e7c0dc

Browse files
committed
Convert FileName.combine to use D slices
1 parent fe5b858 commit 5e7c0dc

1 file changed

Lines changed: 44 additions & 17 deletions

File tree

src/dmd/root/filename.d

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -295,39 +295,66 @@ nothrow:
295295
return f;
296296
}
297297

298+
/**
299+
Combine a `path` and a file `name`
300+
301+
Params:
302+
path = Path to append to
303+
name = Name to append to path
304+
305+
Returns:
306+
The `\0` terminated string which is the combination of `path` and `name`
307+
and a valid path.
308+
*/
298309
extern (C++) static const(char)* combine(const(char)* path, const(char)* name)
299310
{
300-
char* f;
301-
size_t pathlen;
302-
size_t namelen;
303-
if (!path || !*path)
304-
return cast(char*)name;
305-
pathlen = strlen(path);
306-
namelen = strlen(name);
307-
f = cast(char*)mem.xmalloc(pathlen + 1 + namelen + 1);
308-
memcpy(f, path, pathlen);
311+
if (!path)
312+
return name;
313+
return combine(path.toDString, name.toDString).ptr;
314+
}
315+
316+
/// Ditto
317+
extern(D) static const(char)[] combine(const(char)[] path, const(char)[] name)
318+
{
319+
if (!path.length)
320+
return name;
321+
322+
char* f = cast(char*)mem.xmalloc(path.length + 1 + name.length + 1);
323+
memcpy(f, path.ptr, path.length);
324+
bool trailingSlash = false;
309325
version (Posix)
310326
{
311-
if (path[pathlen - 1] != '/')
327+
if (path[$ - 1] != '/')
312328
{
313-
f[pathlen] = '/';
314-
pathlen++;
329+
f[path.length] = '/';
330+
trailingSlash = true;
315331
}
316332
}
317333
else version (Windows)
318334
{
319-
if (path[pathlen - 1] != '\\' && path[pathlen - 1] != '/' && path[pathlen - 1] != ':')
335+
if (path[$ - 1] != '\\' && path[$ - 1] != '/' && path[$ - 1] != ':')
320336
{
321-
f[pathlen] = '\\';
322-
pathlen++;
337+
f[path.length] = '\\';
338+
trailingSlash = true;
323339
}
324340
}
325341
else
326342
{
327343
assert(0);
328344
}
329-
memcpy(f + pathlen, name, namelen + 1);
330-
return f;
345+
const len = path.length + trailingSlash;
346+
memcpy(f + len, name.ptr, name.length);
347+
// Note: At the moment `const(char)*` are being transitioned to
348+
// `const(char)[]`. To avoid bugs crippling in, we `\0` terminate
349+
// slices, but don't include it in the slice so `.ptr` can be used.
350+
f[len + name.length] = '\0';
351+
return f[0 .. len + name.length];
352+
}
353+
354+
unittest
355+
{
356+
assert(combine("foo"[], "bar"[]) == "foo/bar");
357+
assert(combine("foo/"[], "bar"[]) == "foo/bar");
331358
}
332359

333360
static const(char)* buildPath(const(char)* path, const(char)*[] names...)

0 commit comments

Comments
 (0)