[Refactor] Some more C string removal#8592
Conversation
|
Thanks for your pull request and interest in making D better, @Geod24! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + dmd#8592" |
802e5c8 to
58ecfc5
Compare
src/dmd/doc.d
Outdated
| } | ||
|
|
||
| extern (C++) int icmp(const(char)* stringz, const(void)* s, size_t slen) | ||
| private bool icmp(const(char)* stringz, const(char)* s, size_t slen) |
There was a problem hiding this comment.
Isn’t the name a bit misleading now when it will only make a comparison.
There was a problem hiding this comment.
Definitely. Any suggestion ?
There was a problem hiding this comment.
equal, iequal, equali, equalCaseInsensitive.
58ecfc5 to
c5c7bf9
Compare
src/dmd/doc.d
Outdated
| null | ||
| ]; | ||
| for (size_t i = 0; table[i]; i++) | ||
| foreach (const entry; table) |
There was a problem hiding this comment.
The const is redundant, as table is immutable.
src/dmd/doc.d
Outdated
| extern (C++) int icmp(const(char)* stringz, const(void)* s, size_t slen) | ||
| private bool icmp(const(char)* stringz, const(char)* s, size_t slen) | ||
| { | ||
| size_t len1 = strlen(stringz); |
There was a problem hiding this comment.
Your fixes make all the first arguments to icmp a string, but then they get coerced to pointers by the parameter type, and then strlen is run on them here. Just commit to having string parameters to icmp.
src/dmd/doc.d
Outdated
| return cast(int)(len1 - slen); | ||
| return Port.memicmp(stringz, cast(char*)s, slen); | ||
| return false; | ||
| return Port.memicmp(stringz, s, slen) == 0; |
There was a problem hiding this comment.
Give up on pointer-based memicmp and just write a loop.
src/dmd/errors.d
Outdated
| loc.filename = filename; | ||
| loc.linnum = linnum; | ||
| loc.charnum = charnum; | ||
| Loc loc = Loc(filename, linnum, charnum); |
0c3e225 to
1f5b35d
Compare
|
Updated:
|
src/dmd/root/port.d
Outdated
| Returns: | ||
| `true` if `s1 == s2` regardless of case | ||
| */ | ||
| extern(D) static int iequals(const char[] s1, const char[] s2) |
There was a problem hiding this comment.
- Returns
intinstead ofbool - Is if worth mentioning in the documentation that this only works with ASCII (as far as I can tell)?
1f5b35d to
815d722
Compare
|
Updated according to Jacob's comments: diff --git a/src/dmd/root/port.d b/src/dmd/root/port.d
index ea52b617b..01ef74d53 100644
--- a/src/dmd/root/port.d
+++ b/src/dmd/root/port.d
@@ -57,6 +57,9 @@ extern (C++) struct Port
/**
Compare two slices for equality, in a case-insensitive way
+ Comparison is based on `char` and does not do decoding.
+ As a result, it's only really accurate for plain ASCII strings.
+
Params:
s1 = string to compare
s2 = string to compare
@@ -64,7 +67,7 @@ extern (C++) struct Port
Returns:
`true` if `s1 == s2` regardless of case
*/
- extern(D) static int iequals(const char[] s1, const char[] s2)
+ extern(D) static bool iequals(const(char)[] s1, const(char)[] s2)
{
if (s1.length != s2.length)
return false; |
Those constants are not exported to the C++ header, so there is no point to have them extern(C++) __gshared when the can just be immutable.
815d722 to
fc76c62
Compare
src/dmd/doc.d
Outdated
| if (Port.iequals(entry, name[0 .. namelen])) | ||
| { | ||
| buf.printf("$(DDOC_%s ", table[i]); | ||
| buf.printf("$(DDOC_%.*s ", entry.length, entry.ptr); |
There was a problem hiding this comment.
When using .*s, you must cast the entry.length parameter to int, because entry.length is a size_t.
Also, this change to .*s doesn't buy anything anyway, since the string is guaranteed to be 0 terminated.
There was a problem hiding this comment.
I reverted this bit to .ptr
Printing is the main issue I encountered when converting pointers to slices, and I think we need a more convenient way to print slices for it to move forward.
fc76c62 to
4440e8a
Compare
src/dmd/root/port.d
Outdated
| Returns: | ||
| `true` if `s1 == s2` regardless of case | ||
| */ | ||
| extern(D) static bool iequals(const(char)[] s1, const(char)[] s2) |
There was a problem hiding this comment.
Nitpick: Port was originally intended to encapsulate platform-specific code, hence the name.
There was a problem hiding this comment.
I was a bit surprised too, but decided to go with consistency.
Moved iequals to utils
4440e8a to
83f93d3
Compare
src/dmd/dinifile.d
Outdated
| if (!writeToEnv(environment, strdup(pn))) | ||
| { | ||
| error(Loc(filename, lineNum, 0), "Use `NAME=value` syntax, not `%s`", pn); | ||
| error(filename, lineNum, 0, "Use `NAME=value` syntax, not `%s`", pn); |
There was a problem hiding this comment.
This is imho a regression in legibility/code quality. If you want to eliminate an overload, I'd prefer getting rid of the non-Loc one.
There was a problem hiding this comment.
You're right, I only considered the fact that this overload was used in only one place.
However changing this is a bit more involved and would trigger other changes, so I simply removed this commit from this PR and will do the changes in a separate PR.
83f93d3 to
3bf2778
Compare
| case ' ': | ||
| case '\t': | ||
| case '\n': | ||
| continue; |
There was a problem hiding this comment.
This is personal taste, but I found the continue version easier to read, as it can't be confused with breaking out of the loop.
src/dmd/imphint.d
Outdated
| { | ||
| return hints.get(cast(string) s[0..strlen(s)], null).ptr; | ||
| if (auto ptr = s.toDString() in hints) | ||
| return (*ptr).ptr; |
There was a problem hiding this comment.
Not sure if anything containing the snippet (*ptr).ptr can qualify as an improvement…
src/dmd/link.d
Outdated
| version (OSX) | ||
| { | ||
| __gshared const(char)* nmeErrorMessage = "`__Dmain`, referenced from:"; | ||
| static immutable nmeErrorMessage = "`__Dmain`, referenced from:"; |
There was a problem hiding this comment.
Imho a raw pointer is more appropriate as long as it's only used as a C string as it encodes the presence of a null character by convention. Again just a question of style, though.
|
@Geod24: Feel free to auto-merge if you don't want to spend any time discussing stylistics… |
This was previously used in doc, however as we move more towards slice, the code could be simplified to the point it had to be removed. Newly added `dmd.utils : iequals` will perform a case-insensitive string comparison of two slices.
3bf2778 to
f55173e
Compare
|
Updated: diff --git a/src/dmd/imphint.d b/src/dmd/imphint.d
index 95f6319f0..57631750a 100644
--- a/src/dmd/imphint.d
+++ b/src/dmd/imphint.d
@@ -23,8 +23,8 @@ import dmd.utils;
*/
extern (C++) const(char)* importHint(const(char)* s)
{
- if (auto ptr = s.toDString() in hints)
- return (*ptr).ptr;
+ if (auto entry = s.toDString() in hints)
+ return entry.ptr;
return null;
}
diff --git a/src/dmd/doc.d b/src/dmd/doc.d
index 60b9b724d..44fc81782 100644
--- a/src/dmd/doc.d
+++ b/src/dmd/doc.d
@@ -1846,7 +1846,7 @@ extern (D) const(char)[] skipwhitespace(const(char)[] p)
case ' ':
case '\t':
case '\n':
- break;
+ continue;
default:
return p[idx .. $];
}
diff --git a/src/dmd/link.d b/src/dmd/link.d
index 3334d2e0a..2d67e08e0 100644
--- a/src/dmd/link.d
+++ b/src/dmd/link.d
@@ -112,11 +112,11 @@ version (Posix)
{
version (OSX)
{
- static immutable nmeErrorMessage = "`__Dmain`, referenced from:";
+ static immutable(char*) nmeErrorMessage = "`__Dmain`, referenced from:";
}
else
{
- static immutable nmeErrorMessage = "undefined reference to `_Dmain`";
+ static immutable(char*) nmeErrorMessage = "undefined reference to `_Dmain`";
}
FILE* stream = fdopen(fd, "r");
if (stream is null)
@@ -136,7 +136,7 @@ version (Posix)
const(char)* lastSep = strrchr(buffer.ptr, '\n');
if (lastSep)
buffer[(end = lastSep - &buffer[0])] = '\0';
- if (strstr(&buffer[0], nmeErrorMessage.ptr))
+ if (strstr(&buffer[0], nmeErrorMessage))
nmeFound = true;
if (lastSep)
buffer[end++] = '\n'; |
|
Well this is green with auto-merge but dlang bot doesn't care, so merging manually |
A few more commits cleaning up strings while we wait on #8585 .