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
12 changes: 12 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -1500,3 +1500,15 @@ Version history
- add "Step Over Foreach" command
* dbuild: generic support for VS 2026 18.1-18.15
* added command "Step Over Foreach"

2026-08-28 version 1.5.0-rc3
* dmdserver:
- improve intellisense in __traits
- define version VisualDServer to allow ensuring template instances
- removed more stale pointers reducing memory requirements
* fix reading ldc2.conf for LDC 1.42+ from subdirectories

2026-08-29 version 1.5.0
* full installer now bundled with DMD 2.113.o and LDC 1.43.0
* dmdserver:
- updated to dmd 2.114-beta1
4 changes: 2 additions & 2 deletions VERSION
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 5
#define VERSION_REVISION 0
#define VERSION_BETA -rc
#define VERSION_BUILD 2
#define VERSION_BETA
#define VERSION_BUILD 0
149 changes: 95 additions & 54 deletions nsis/visuald.nsi

Large diffs are not rendered by default.

117 changes: 80 additions & 37 deletions stdext/libconfig.d
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Setting
group,
}

this(string name, Type type)
this(string name, Type type) pure
{
_name = name;
_type = type;
Expand Down Expand Up @@ -91,18 +91,25 @@ class ScalarSetting : Setting

class ArraySetting : Setting
{
this(string name, string[] vals)
this(string name, string[] vals, bool isAppending)
{
super(name, Type.array);
_vals = vals;
_isAppending = isAppending;
}

@property const(string)[] vals() const
{
return _vals;
}

@property bool isAppending() const
{
return _isAppending;
}

private string[] _vals;
private bool _isAppending;
}

class GroupSetting : Setting
Expand Down Expand Up @@ -175,7 +182,7 @@ EBNF grammar.
It is a subset of the libconfig grammar (http://www.hyperrealm.com/libconfig).

config = { ows , setting } , ows ;
setting = (name | string) , (":" | "=") , value , [";" | ","] ;
setting = (name | string) , (":" | "=" | "~=") , value , [";" | ","] ;
name = alpha , { alpha | digit | "_" | "-" } ;
value = string | array | group ;
array = "[" , ows ,
Expand Down Expand Up @@ -214,6 +221,7 @@ enum Token
{
name,
assign, // ':' or '='
appendAssign, // '~='
str,
lbrace, // '{'
rbrace, // '}'
Expand All @@ -229,17 +237,18 @@ string humanReadableToken(in Token tok)
{
final switch(tok)
{
case Token.name: return `"name"`;
case Token.assign: return `':' or '='`;
case Token.str: return `"string"`;
case Token.lbrace: return `'{'`;
case Token.rbrace: return `'}'`;
case Token.lbracket: return `'['`;
case Token.rbracket: return `']'`;
case Token.semicolon: return `';'`;
case Token.comma: return `','`;
case Token.unknown: return `"unknown token"`;
case Token.eof: return `"end of file"`;
case Token.name: return `"name"`;
case Token.assign: return `':' or '='`;
case Token.appendAssign: return `'~='`;
case Token.str: return `"string"`;
case Token.lbrace: return `'{'`;
case Token.rbrace: return `'}'`;
case Token.lbracket: return `'['`;
case Token.rbracket: return `']'`;
case Token.semicolon: return `';'`;
case Token.comma: return `','`;
case Token.unknown: return `"unknown token"`;
case Token.eof: return `"end of file"`;
}
}

Expand Down Expand Up @@ -268,11 +277,14 @@ struct Parser

void error(in string msg)
{
enum fmt = "Error while reading config file: %.*s\nline %d: %.*s";
char[1024] buf;
auto len = snprintf(buf.ptr, cast(int)buf.length, fmt, cast(int)filename.length,
filename.ptr, lineNum, cast(int)msg.length, msg.ptr);
throw new Exception(buf[0 .. len].idup);
error(msg, lineNum);
}

void error(in string msg, int lineNum)
{
char[20] buf = void;
auto len = snprintf(buf.ptr, buf.length, "line %d: ", lineNum);
throw new Exception((cast(string) buf[0 .. len]) ~ msg);
}

char getChar()
Expand Down Expand Up @@ -317,6 +329,19 @@ struct Parser
return getTok(outStr);
}

if (lastChar == '~')
{
lastChar = getChar();
if (lastChar != '=')
{
outStr = "~";
return Token.unknown;
}

lastChar = getChar();
return Token.appendAssign;
}

if (isalpha(lastChar))
{
string name;
Expand Down Expand Up @@ -452,17 +477,6 @@ struct Parser
". Got " ~ humanReadableToken(tok) ~ s ~ " instead.");
}

string accept(in Token expected)
{
string s;
immutable tok = getTok(s);
if (tok != expected)
{
unexpectedTokenError(tok, expected, s);
}
return s;
}

Setting[] parseConfig()
{
Setting[] res;
Expand Down Expand Up @@ -492,11 +506,29 @@ struct Parser
assert(false);
}

accept(Token.assign);
string s;
t = getTok(s);
if (t != Token.assign && t != Token.appendAssign)
{
auto msg = "Expected either"
~ " token " ~ humanReadableToken(Token.assign)
~ " or token " ~ humanReadableToken(Token.appendAssign)
~ " but got: " ~ humanReadableToken(t)
~ ' ' ~ (s.length ? '(' ~ s ~ ')' : s);
error(msg);
}
// This is off by +1 if `t` is followed by \n
const assignLineNum = lineNum;

Setting res = parseValue(name);
Setting res = parseValue(name, t);
if (t == Token.appendAssign)
{
if (res.type == Setting.Type.scalar)
error(humanReadableToken(t) ~ " is not supported with scalar values", assignLineNum);
if (res.type == Setting.Type.group)
error(humanReadableToken(t) ~ " is not supported with groups", assignLineNum);
}

string s;
t = getTok(s);
if (t != Token.semicolon && t != Token.comma)
{
Expand All @@ -506,8 +538,10 @@ struct Parser
return res;
}

Setting parseValue(string name)
Setting parseValue(string name, Token tAssign = Token.assign)
{
assert(tAssign == Token.assign || tAssign == Token.appendAssign);

string s;
auto t = getTok(s);
if (t == Token.str)
Expand All @@ -516,6 +550,7 @@ struct Parser
}
else if (t == Token.lbracket)
{
const isAppending = tAssign == Token.appendAssign;
string[] arrVal;
while (1)
{
Expand All @@ -527,7 +562,7 @@ struct Parser
arrVal ~= s;
break;
case Token.rbracket:
return new ArraySetting(name, arrVal);
return new ArraySetting(name, arrVal, isAppending);
default:
unexpectedTokenError(t, Token.str, s);
assert(false);
Expand All @@ -540,7 +575,7 @@ struct Parser
case Token.comma:
break;
case Token.rbracket:
return new ArraySetting(name, arrVal);
return new ArraySetting(name, arrVal, isAppending);
default:
unexpectedTokenError(t, Token.comma, s);
assert(false);
Expand Down Expand Up @@ -620,6 +655,8 @@ group-1_2: {};
scalar = "abc";
// comment
Array_1-2 = [ "a" ];

AppArray ~= [ "x" ]; // appending array
};
`;

Expand All @@ -633,7 +670,7 @@ group-1_2: {};
assert(settings[1].name == "86(_64)?-.*linux\\.?");
assert(settings[1].type == Setting.Type.group);
auto group2 = cast(GroupSetting) settings[1];
assert(group2.children.length == 2);
assert(group2.children.length == 3);

assert(group2.children[0].name == "scalar");
assert(group2.children[0].type == Setting.Type.scalar);
Expand All @@ -642,4 +679,10 @@ group-1_2: {};
assert(group2.children[1].name == "Array_1-2");
assert(group2.children[1].type == Setting.Type.array);
assert((cast(ArraySetting) group2.children[1]).vals == [ "a" ]);
assert((cast(ArraySetting) group2.children[1]).isAppending == false);

assert(group2.children[2].name == "AppArray");
assert(group2.children[2].type == Setting.Type.array);
assert((cast(ArraySetting) group2.children[2]).vals == [ "x" ]);
assert((cast(ArraySetting) group2.children[2]).isAppending == true);
}
33 changes: 20 additions & 13 deletions tools/pipedmd.d
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ static import std.file;
import stdext.string : decodeDmdString;

pragma(lib, "user32");
pragma(lib, "kernel32");
pragma(lib, "ole32");
pragma(lib, "oleaut32");

extern(Windows) BOOL QueryProcessCycleTime(HANDLE ProcessHandle, PULONG64 CycleTime);

// version = pipeLink; // define to forward arguments to link.exe and demangle its output
version = MSLinkFormat;
Expand Down Expand Up @@ -100,7 +105,7 @@ int main(string[] argv)
printf("decompresses and demangles names in OPTLINK and ld messages\n");
printf("\n");
printf("usage: %.*s [-nodemangle] [-gdcmode | -msmode] [-deps depfile] [executable] [arguments]\n",
argv[0].length, argv[0].ptr);
cast(int)argv[0].length, argv[0].ptr);
return -1;
}
int skipargs = 0;
Expand Down Expand Up @@ -171,9 +176,9 @@ int main(string[] argv)
if (verbose)
{
if (fullexe.empty)
printf ("%.*s not found in PATH, assuming %d-bit application\n", exe.length, exe.ptr, isX64 ? 64 : 32);
printf ("%.*s not found in PATH, assuming %d-bit application\n", cast(int)exe.length, exe.ptr, isX64 ? 64 : 32);
else
printf ("%.*s is a %d-bit application\n", fullexe.length, fullexe.ptr, isX64 ? 64 : 32);
printf ("%.*s is a %d-bit application\n", cast(int)fullexe.length, fullexe.ptr, isX64 ? 64 : 32);
}
string trackerArgs;
string tracker = findTracker(isX64, trackerArgs);
Expand All @@ -195,7 +200,7 @@ int main(string[] argv)
}
else if (isX64 || !canInjectDLL)
{
printf("cannot monitor %d-bit executable %.*s, no suitable tracker.exe found\n", isX64 ? 64 : 32, exe.length, exe.ptr);
printf("cannot monitor %d-bit executable %.*s, no suitable tracker.exe found\n", isX64 ? 64 : 32, cast(int)exe.length, exe.ptr);
return -1;
}
else
Expand All @@ -209,7 +214,7 @@ int main(string[] argv)
command ~= quoteArg(argv[i]);
}
if(verbose)
printf("Command: %.*s\n", command.length, command.ptr);
printf("Command: %.*s\n", cast(int)command.length, command.ptr);

int exitCode = runProcess(command, inject ? depsfile : null, doDemangle, demangleAll, gdcMode, msMode, memStats);

Expand Down Expand Up @@ -381,15 +386,17 @@ int runProcess(string command, string depsfile, bool doDemangle, bool demangleAl
}

if (memStats)
{
PROCESS_MEMORY_COUNTERS memCounters;
string procName = getProcessName(piProcInfo.hProcess);
if (auto fun = getProcessMemoryInfoFunc())
{
string procName = getProcessName(piProcInfo.hProcess);
PROCESS_MEMORY_COUNTERS memCounters;
bSuccess = fun(piProcInfo.hProcess, &memCounters, memCounters.sizeof);
if (bSuccess)
printf("%s used %lld MB of private memory\n", procName.ptr,
cast(long)memCounters.PeakPagefileUsage >> 20);
}
fun(piProcInfo.hProcess, &memCounters, memCounters.sizeof);
ulong cycleTime;
QueryProcessCycleTime(piProcInfo.hProcess, &cycleTime);

printf("%s used %lld MB of private memory, %llu Mcycles\n", procName.ptr,
cast(long)memCounters.PeakPagefileUsage >> 20, cycleTime >> 20);
}

//close the handles to the process
CloseHandle(hStdInWrite);
Expand Down
Loading
Loading