Skip to content

Commit 0ec33ca

Browse files
the-horoWebFreak001
authored andcommitted
source/external/ldc/config.d: Backport upstream ~= operator addition
Since version 1.41.0 the official ldc2 packages for macos started using this operator in the configuration files which makes serve-d fail to initialize. Bug: dlang-community/DCD#787 See-Also: ldc-developers/ldc#4856 Signed-off-by: Andrei Horodniceanu <a.horodniceanu@proton.me>
1 parent 8721ce7 commit 0ec33ca

File tree

2 files changed

+85
-36
lines changed

2 files changed

+85
-36
lines changed

source/external/ldc/config.d

Lines changed: 79 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,25 @@ class ScalarSetting : Setting
7070

7171
class ArraySetting : Setting
7272
{
73-
this(string name, string[] vals)
73+
this(string name, string[] vals, bool isAppending)
7474
{
7575
super(name, Type.array);
7676
_vals = vals;
77+
_isAppending = isAppending;
7778
}
7879

7980
@property const(string)[] vals() const
8081
{
8182
return _vals;
8283
}
8384

85+
@property bool isAppending() const
86+
{
87+
return _isAppending;
88+
}
89+
8490
private string[] _vals;
91+
private bool _isAppending;
8592
}
8693

8794
class GroupSetting : Setting
@@ -125,7 +132,7 @@ EBNF grammar.
125132
It is a subset of the libconfig grammar (http://www.hyperrealm.com/libconfig).
126133
127134
config = { ows , setting } , ows ;
128-
setting = (name | string) , (":" | "=") , value , [";" | ","] ;
135+
setting = (name | string) , (":" | "=" | "~=") , value , [";" | ","] ;
129136
name = alpha , { alpha | digit | "_" | "-" } ;
130137
value = string | array | group ;
131138
array = "[" , ows ,
@@ -164,6 +171,7 @@ enum Token
164171
{
165172
name,
166173
assign, // ':' or '='
174+
appendAssign, // '~='
167175
str,
168176
lbrace, // '{'
169177
rbrace, // '}'
@@ -179,17 +187,18 @@ string humanReadableToken(in Token tok)
179187
{
180188
final switch(tok)
181189
{
182-
case Token.name: return `"name"`;
183-
case Token.assign: return `':' or '='`;
184-
case Token.str: return `"string"`;
185-
case Token.lbrace: return `'{'`;
186-
case Token.rbrace: return `'}'`;
187-
case Token.lbracket: return `'['`;
188-
case Token.rbracket: return `']'`;
189-
case Token.semicolon: return `';'`;
190-
case Token.comma: return `','`;
191-
case Token.unknown: return `"unknown token"`;
192-
case Token.eof: return `"end of file"`;
190+
case Token.name: return `"name"`;
191+
case Token.assign: return `':' or '='`;
192+
case Token.appendAssign: return `'~='`;
193+
case Token.str: return `"string"`;
194+
case Token.lbrace: return `'{'`;
195+
case Token.rbrace: return `'}'`;
196+
case Token.lbracket: return `'['`;
197+
case Token.rbracket: return `']'`;
198+
case Token.semicolon: return `';'`;
199+
case Token.comma: return `','`;
200+
case Token.unknown: return `"unknown token"`;
201+
case Token.eof: return `"end of file"`;
193202
}
194203
}
195204

@@ -218,11 +227,14 @@ struct Parser
218227

219228
void error(in string msg)
220229
{
221-
enum fmt = "Error while reading config file: %.*s\nline %d: %.*s";
222-
char[1024] buf;
223-
auto len = snprintf(buf.ptr, buf.length, fmt, cast(int) filename.length,
224-
filename.ptr, lineNum, cast(int) msg.length, msg.ptr);
225-
throw new Exception(buf[0 .. len].idup);
230+
error(msg, lineNum);
231+
}
232+
233+
void error(in string msg, int lineNum)
234+
{
235+
char[20] buf = void;
236+
auto len = snprintf(buf.ptr, buf.length, "line %d: ", lineNum);
237+
throw new Exception((cast(string) buf[0 .. len]) ~ msg);
226238
}
227239

228240
char getChar()
@@ -267,6 +279,19 @@ struct Parser
267279
return getTok(outStr);
268280
}
269281

282+
if (lastChar == '~')
283+
{
284+
lastChar = getChar();
285+
if (lastChar != '=')
286+
{
287+
outStr = "~";
288+
return Token.unknown;
289+
}
290+
291+
lastChar = getChar();
292+
return Token.appendAssign;
293+
}
294+
270295
if (isalpha(lastChar))
271296
{
272297
string name;
@@ -402,17 +427,6 @@ struct Parser
402427
". Got " ~ humanReadableToken(tok) ~ s ~ " instead.");
403428
}
404429

405-
string accept(in Token expected)
406-
{
407-
string s;
408-
immutable tok = getTok(s);
409-
if (tok != expected)
410-
{
411-
unexpectedTokenError(tok, expected, s);
412-
}
413-
return s;
414-
}
415-
416430
Setting[] parseConfig()
417431
{
418432
Setting[] res;
@@ -442,11 +456,29 @@ struct Parser
442456
assert(false);
443457
}
444458

445-
accept(Token.assign);
459+
string s;
460+
t = getTok(s);
461+
if (t != Token.assign && t != Token.appendAssign)
462+
{
463+
auto msg = "Expected either"
464+
~ " token " ~ humanReadableToken(Token.assign)
465+
~ " or token " ~ humanReadableToken(Token.appendAssign)
466+
~ " but got: " ~ humanReadableToken(t)
467+
~ ' ' ~ (s.length ? '(' ~ s ~ ')' : s);
468+
error(msg);
469+
}
470+
// This is off by +1 if `t` is followed by \n
471+
const assignLineNum = lineNum;
446472

447-
Setting res = parseValue(name);
473+
Setting res = parseValue(name, t);
474+
if (t == Token.appendAssign)
475+
{
476+
if (res.type == Setting.Type.scalar)
477+
error(humanReadableToken(t) ~ " is not supported with scalar values", assignLineNum);
478+
if (res.type == Setting.Type.group)
479+
error(humanReadableToken(t) ~ " is not supported with groups", assignLineNum);
480+
}
448481

449-
string s;
450482
t = getTok(s);
451483
if (t != Token.semicolon && t != Token.comma)
452484
{
@@ -456,8 +488,10 @@ struct Parser
456488
return res;
457489
}
458490

459-
Setting parseValue(string name)
491+
Setting parseValue(string name, Token tAssign = Token.assign)
460492
{
493+
assert(tAssign == Token.assign || tAssign == Token.appendAssign);
494+
461495
string s;
462496
auto t = getTok(s);
463497
if (t == Token.str)
@@ -466,6 +500,7 @@ struct Parser
466500
}
467501
else if (t == Token.lbracket)
468502
{
503+
const isAppending = tAssign == Token.appendAssign;
469504
string[] arrVal;
470505
while (1)
471506
{
@@ -477,7 +512,7 @@ struct Parser
477512
arrVal ~= s;
478513
break;
479514
case Token.rbracket:
480-
return new ArraySetting(name, arrVal);
515+
return new ArraySetting(name, arrVal, isAppending);
481516
default:
482517
unexpectedTokenError(t, Token.str, s);
483518
assert(false);
@@ -490,7 +525,7 @@ struct Parser
490525
case Token.comma:
491526
break;
492527
case Token.rbracket:
493-
return new ArraySetting(name, arrVal);
528+
return new ArraySetting(name, arrVal, isAppending);
494529
default:
495530
unexpectedTokenError(t, Token.comma, s);
496531
assert(false);
@@ -570,6 +605,8 @@ group-1_2: {};
570605
scalar = "abc";
571606
// comment
572607
Array_1-2 = [ "a" ];
608+
609+
AppArray ~= [ "x" ]; // appending array
573610
};
574611
`;
575612

@@ -583,7 +620,7 @@ group-1_2: {};
583620
assert(settings[1].name == "86(_64)?-.*linux\\.?");
584621
assert(settings[1].type == Setting.Type.group);
585622
auto group2 = cast(GroupSetting) settings[1];
586-
assert(group2.children.length == 2);
623+
assert(group2.children.length == 3);
587624

588625
assert(group2.children[0].name == "scalar");
589626
assert(group2.children[0].type == Setting.Type.scalar);
@@ -592,4 +629,10 @@ group-1_2: {};
592629
assert(group2.children[1].name == "Array_1-2");
593630
assert(group2.children[1].type == Setting.Type.array);
594631
assert((cast(ArraySetting) group2.children[1]).vals == [ "a" ]);
632+
assert((cast(ArraySetting) group2.children[1]).isAppending == false);
633+
634+
assert(group2.children[2].name == "AppArray");
635+
assert(group2.children[2].type == Setting.Type.array);
636+
assert((cast(ArraySetting) group2.children[2]).vals == [ "x" ]);
637+
assert((cast(ArraySetting) group2.children[2]).isAppending == true);
595638
}

source/served/utils/stdlib_detect.d

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,12 @@ bool parseLdcConfImports(string confPath, scope const(char)[] binDirPath, out st
388388
}
389389

390390
trace("test ldc conf ", confPath);
391+
Setting[] settings;
392+
try
393+
settings = parseConfigFile(confPath);
394+
catch (Exception e)
395+
throw new Exception("Could not read ldc2 config file: " ~ confPath ~ ": " ~ e.msg);
396+
391397
foreach (s; parseConfigFile(confPath))
392398
{
393399
if (s.type == Setting.Type.group && s.name == "default")

0 commit comments

Comments
 (0)