Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dmd/dmodule.d
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,7 @@ extern (C++) final class Module : Package
assert(prev);
if (Module mprev = prev.isModule())
{
if (FileName.compare(srcname, mprev.srcfile.toChars()) != 0)
if (!FileName.equals(srcname, mprev.srcfile.toChars()))
error(loc, "from file %s conflicts with another module %s from file %s", srcname, mprev.toChars(), mprev.srcfile.toChars());
else if (isRoot() && mprev.isRoot())
error(loc, "from file %s is specified twice on the command line", srcname);
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/dmsc.d
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void backend_init()
exe = true; // EXE file only optimizations
else if (params.exefile) // if writing out EXE file
{ size_t len = strlen(params.exefile);
if (len >= 4 && FileName.compare(params.exefile + len - 3, "exe") == 0)
if (len >= 4 && FileName.equals(params.exefile + len - 3, "exe"))
exe = true;
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1533,13 +1533,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
else
ob.writestring("???");
ob.writeByte(')');
for (size_t i = 0; i < imp.names.dim; i++)
foreach (i, name; imp.names)
{
if (i == 0)
ob.writeByte(':');
else
ob.writeByte(',');
Identifier name = imp.names[i];
Identifier _alias = imp.aliases[i];
if (!_alias)
{
Expand Down
9 changes: 3 additions & 6 deletions src/dmd/mars.d
Original file line number Diff line number Diff line change
Expand Up @@ -878,11 +878,8 @@ private int tryMain(size_t argc, const(char)** argv)
library = Library.factory();
library.setFilename(global.params.objdir, global.params.libname);
// Add input object and input library files to output library
for (size_t i = 0; i < libmodules.dim; i++)
{
const(char)* p = libmodules[i];
foreach (p; libmodules)
library.addObject(p, null);
}
}
// Generate output files
if (global.params.doJsonGeneration)
Expand Down Expand Up @@ -2243,8 +2240,8 @@ private bool parseCommandLine(const ref Strings arguments, const size_t argc, re
{
static if (TARGET.Windows)
{
const(char)* ext = FileName.ext(p);
if (ext && FileName.compare(ext, "exe") == 0)
const ext = FileName.ext(p);
if (ext && FileName.equals(ext, "exe"))
{
params.objname = p;
continue;
Expand Down
4 changes: 0 additions & 4 deletions src/dmd/root/file.d
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,6 @@ nothrow:
}
else version (Windows)
{
import dmd.root.filename: extendedPathThen;

DWORD size;
DWORD numread;

Expand Down Expand Up @@ -272,8 +270,6 @@ nothrow:
}
else version (Windows)
{
import dmd.root.filename: extendedPathThen;

DWORD numwritten; // here because of the gotos
const(char)* name = this.name.toChars();
// work around Windows file path length limitation
Expand Down
87 changes: 55 additions & 32 deletions src/dmd/root/filename.d
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ import core.sys.windows.windows;
import dmd.root.array;
import dmd.root.file;
import dmd.root.outbuffer;
import dmd.root.port;
import dmd.root.rmem;
import dmd.root.rootobject;
import dmd.utils;

nothrow
{
version (Windows) extern (C) int stricmp(const char*, const char*) pure;
version (Windows) extern (Windows) DWORD GetFullPathNameW(LPCWSTR, DWORD, LPWSTR, LPWSTR*) @nogc;
version (Windows) extern (Windows) void SetLastError(DWORD) @nogc;
version (Windows) extern (C) char* getcwd(char* buffer, size_t maxlen);
Expand All @@ -49,30 +50,25 @@ nothrow:
this.str = mem.xstrdup(str);
}

extern (C++) bool equals(const RootObject obj) const pure
{
return compare(obj) == 0;
}

/// Compare two name according to the platform's rules (case sensitive or not)
extern (C++) static bool equals(const(char)* name1, const(char)* name2) pure
{
return compare(name1, name2) == 0;
return equals(name1.toDString, name2.toDString);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be more efficient to keep the C compare here for now?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That difference is negligible.

And if we concern ourselves with such micro-optimization, there's very little I can do, as most of the work of converting involves moving the implementation to slices and providing strlen wrapper, which isn't strictly necessary sometimes (like here).

The other approach would be to convert all the code that relies on it at once, but that applies transitively, and you end up converting all the code of DMD to use slice, which is clearly not feasible.

}

extern (C++) int compare(const RootObject obj) const pure
/// Ditto
extern (D) static bool equals(const(char)[] name1, const(char)[] name2) pure
{
return compare(str, (cast(FileName*)obj).str);
}
if (name1.length != name2.length)
return false;

extern (C++) static int compare(const(char)* name1, const(char)* name2) pure
{
version (Windows)
{
return stricmp(name1, name2);
return Port.memicmp(name1.ptr, name2.ptr, name1.length) == 0;
}
else
{
return strcmp(name1, name2);
return name1 == name2;
}
}

Expand Down Expand Up @@ -299,39 +295,66 @@ nothrow:
return f;
}

/**
Combine a `path` and a file `name`

Params:
path = Path to append to
name = Name to append to path

Returns:
The `\0` terminated string which is the combination of `path` and `name`
and a valid path.
*/
extern (C++) static const(char)* combine(const(char)* path, const(char)* name)
{
char* f;
size_t pathlen;
size_t namelen;
if (!path || !*path)
return cast(char*)name;
pathlen = strlen(path);
namelen = strlen(name);
f = cast(char*)mem.xmalloc(pathlen + 1 + namelen + 1);
memcpy(f, path, pathlen);
if (!path)
return name;
return combine(path.toDString, name.toDString).ptr;
}

/// Ditto
extern(D) static const(char)[] combine(const(char)[] path, const(char)[] name)
{
if (!path.length)
return name;

char* f = cast(char*)mem.xmalloc(path.length + 1 + name.length + 1);
memcpy(f, path.ptr, path.length);
bool trailingSlash = false;
version (Posix)
{
if (path[pathlen - 1] != '/')
if (path[$ - 1] != '/')
{
f[pathlen] = '/';
pathlen++;
f[path.length] = '/';
trailingSlash = true;
}
}
else version (Windows)
{
if (path[pathlen - 1] != '\\' && path[pathlen - 1] != '/' && path[pathlen - 1] != ':')
if (path[$ - 1] != '\\' && path[$ - 1] != '/' && path[$ - 1] != ':')
{
f[pathlen] = '\\';
pathlen++;
f[path.length] = '\\';
trailingSlash = true;
}
}
else
{
assert(0);
}
memcpy(f + pathlen, name, namelen + 1);
return f;
const len = path.length + trailingSlash;
memcpy(f + len, name.ptr, name.length);
// Note: At the moment `const(char)*` are being transitioned to
// `const(char)[]`. To avoid bugs crippling in, we `\0` terminate
// slices, but don't include it in the slice so `.ptr` can be used.
f[len + name.length] = '\0';
return f[0 .. len + name.length];
}

unittest
{
assert(combine("foo"[], "bar"[]) == "foo/bar");
assert(combine("foo/"[], "bar"[]) == "foo/bar");
}

static const(char)* buildPath(const(char)* path, const(char)*[] names...)
Expand Down Expand Up @@ -469,7 +492,7 @@ nothrow:
return true;
if (!e || !ext)
return false;
return FileName.compare(e, ext) == 0;
return FileName.equals(e, ext);
}

/******************************
Expand Down
3 changes: 0 additions & 3 deletions src/dmd/root/filename.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ struct FileName
{
const char *str;
FileName(const char *str);
bool equals(RootObject *obj);
static bool equals(const char *name1, const char *name2);
int compare(RootObject *obj);
static int compare(const char *name1, const char *name2);
static bool absolute(const char *name);
static const char *toAbsolute(const char *name, const char *base = NULL);
static const char *ext(const char *);
Expand Down
5 changes: 0 additions & 5 deletions src/dmd/root/outbuffer.d
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,6 @@ struct OutBuffer
offset += nbytes;
}

extern (C++) void writebstring(char* string) nothrow
{
write(string, *string + 1);
}

extern (C++) void writestring(const(char)* string) nothrow
{
write(string, strlen(string));
Expand Down
1 change: 0 additions & 1 deletion src/dmd/root/outbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ struct OutBuffer
void setsize(size_t size);
void reset();
void write(const void *data, d_size_t nbytes);
void writebstring(utf8_t *string);
void writestring(const char *string);
void prependstring(const char *string);
void writenl(); // write newline
Expand Down
26 changes: 15 additions & 11 deletions src/dmd/root/port.d
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import core.stdc.string;
import core.stdc.stdio;
import core.stdc.stdlib;

nothrow @nogc:

private extern (C)
{
version(CRuntime_DigitalMars) __gshared extern const(char)* __locale_decpoint;
Expand All @@ -34,7 +36,9 @@ private extern (C)

extern (C++) struct Port
{
static int memicmp(const char* s1, const char* s2, size_t n)
nothrow @nogc:

static int memicmp(scope const char* s1, scope const char* s2, size_t n) pure
{
int result = 0;

Expand All @@ -54,7 +58,7 @@ extern (C++) struct Port
return result;
}

static char* strupr(char* s)
static char* strupr(char* s) pure
{
char* t = s;

Expand All @@ -67,7 +71,7 @@ extern (C++) struct Port
return t;
}

static bool isFloat32LiteralOutOfRange(const(char)* s)
static bool isFloat32LiteralOutOfRange(scope const(char)* s)
{
errno = 0;
version (CRuntime_DigitalMars)
Expand All @@ -90,7 +94,7 @@ extern (C++) struct Port
return errno == ERANGE;
}

static bool isFloat64LiteralOutOfRange(const(char)* s)
static bool isFloat64LiteralOutOfRange(scope const(char)* s)
{
errno = 0;
version (CRuntime_DigitalMars)
Expand All @@ -114,7 +118,7 @@ extern (C++) struct Port
}

// Little endian
static void writelongLE(uint value, void* buffer)
static void writelongLE(uint value, scope void* buffer) pure
{
auto p = cast(ubyte*)buffer;
p[3] = cast(ubyte)(value >> 24);
Expand All @@ -124,14 +128,14 @@ extern (C++) struct Port
}

// Little endian
static uint readlongLE(void* buffer)
static uint readlongLE(scope void* buffer) pure
{
auto p = cast(ubyte*)buffer;
return (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
}

// Big endian
static void writelongBE(uint value, void* buffer)
static void writelongBE(uint value, scope void* buffer) pure
{
auto p = cast(ubyte*)buffer;
p[0] = cast(ubyte)(value >> 24);
Expand All @@ -141,27 +145,27 @@ extern (C++) struct Port
}

// Big endian
static uint readlongBE(void* buffer)
static uint readlongBE(scope void* buffer) pure
{
auto p = cast(ubyte*)buffer;
return (((((p[0] << 8) | p[1]) << 8) | p[2]) << 8) | p[3];
}

// Little endian
static uint readwordLE(void* buffer)
static uint readwordLE(scope void* buffer) pure
{
auto p = cast(ubyte*)buffer;
return (p[1] << 8) | p[0];
}

// Big endian
static uint readwordBE(void* buffer)
static uint readwordBE(scope void* buffer) pure
{
auto p = cast(ubyte*)buffer;
return (p[0] << 8) | p[1];
}

static void valcpy(void *dst, ulong val, size_t size)
static void valcpy(scope void *dst, ulong val, size_t size) pure
{
switch (size)
{
Expand Down
6 changes: 6 additions & 0 deletions src/dmd/root/stringtable.d
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ pure:
{
return cast(const(char)*)(&this + 1);
}

/// Returns: The content of this entry as a D slice
extern (D) inout(char)[] toString() inout
{
return (cast(inout(char)*)(&this + 1))[0 .. length];
}
}

struct StringTable
Expand Down
Loading