Thread overview
dirEntries within static foreach: memory.d(827): Error: fakePureErrno cannot be interpreted at compile time, because it has no available source code
Feb 11, 2019
kdevel
Feb 11, 2019
Seb
Feb 11, 2019
kdevel
Feb 11, 2019
Seb
Feb 11, 2019
Jonathan M Davis
February 11, 2019
I am trying to get this code compiled:

```TemplateStore.d
module TemplateStore;
import std.path;
import std.conv;
import std.file;

immutable string[string] template_map;

static this ()
{
   static foreach (f; dirEntries (``, `*.html`, SpanMode.shallow)) {
      pragma (msg, `reading template <` ~ f ~ ">");
      template_map[f] = import (f);
   }
}
```

dmd v2.082.0 says

...linux/bin64/../../src/druntime/import/core/memory.d(827): Error: fakePureErrno cannot be interpreted at compile time, because it has no available source code
Error: invalid foreach aggregate <error>
Error: invalid foreach aggregate <error>

If I use an immutable array of file names instead of dirEntries the code compiles, but I don't want to update that array each time a new template file is added.

As a workaround I wrote a helper which writes the quoted filenames comma-separated into a file named `LS` using this fragment:

   foreach (f; dirEntries (``, `*.html`, SpanMode.shallow))
      writefln ("`%s`,", f);

Then I try to convince the dmd compiler to read LS and use its content as initializer for the immutable array template_files:

   immutable LS = import (`LS`);
   pragma (msg, `LS = <` ~ LS ~ `>`);
   immutable template_files = [
      mixin(LS)
   ];

dmd now says (1) if the list in LS has a trailing comma:

   TemplateStore.d-mixin-13(26): Error: expression expected, not End of File

or (2) if the list has no trailing comma:

   TemplateStore.d-mixin-13(13): Error: Using the result of a comma expression is not allowed
   TemplateStore.d-mixin-13(14): Error: Using the result of a comma expression is not allowed
   TemplateStore.d-mixin-13(15): Error: Using the result of a comma expression is not allowed
   :

What can I do about it?





February 11, 2019
On Monday, 11 February 2019 at 00:19:02 UTC, kdevel wrote:
> I am trying to get this code compiled:
>
> ```TemplateStore.d
> module TemplateStore;
> import std.path;
> import std.conv;
> import std.file;
>
> [...]

You can't read or list files at compile-time. What are you trying to do?
February 10, 2019
On Sunday, February 10, 2019 5:19:02 PM MST kdevel via Digitalmars-d-learn wrote:
> I am trying to get this code compiled:
>
> ```TemplateStore.d
> module TemplateStore;
> import std.path;
> import std.conv;
> import std.file;
>
> immutable string[string] template_map;
>
> static this ()
> {
>     static foreach (f; dirEntries (``, `*.html`,
> SpanMode.shallow)) {
>        pragma (msg, `reading template <` ~ f ~ ">");
>        template_map[f] = import (f);
>     }
> }
> ```
>
> dmd v2.082.0 says
>
> ...linux/bin64/../../src/druntime/import/core/memory.d(827):
> Error: fakePureErrno cannot be interpreted at compile time,
> because it has no available source code
> Error: invalid foreach aggregate <error>
> Error: invalid foreach aggregate <error>
>
> If I use an immutable array of file names instead of dirEntries the code compiles, but I don't want to update that array each time a new template file is added.
>
> As a workaround I wrote a helper which writes the quoted filenames comma-separated into a file named `LS` using this fragment:
>
>     foreach (f; dirEntries (``, `*.html`, SpanMode.shallow))
>        writefln ("`%s`,", f);
>
> Then I try to convince the dmd compiler to read LS and use its content as initializer for the immutable array template_files:
>
>     immutable LS = import (`LS`);
>     pragma (msg, `LS = <` ~ LS ~ `>`);
>     immutable template_files = [
>        mixin(LS)
>     ];
>
> dmd now says (1) if the list in LS has a trailing comma:
>
>     TemplateStore.d-mixin-13(26): Error: expression expected, not
> End of File
>
> or (2) if the list has no trailing comma:
>
>     TemplateStore.d-mixin-13(13): Error: Using the result of a
> comma expression is not allowed
>     TemplateStore.d-mixin-13(14): Error: Using the result of a
> comma expression is not allowed
>     TemplateStore.d-mixin-13(15): Error: Using the result of a
> comma expression is not allowed
>
>
> What can I do about it?

Nothing. You can't call C functions during CTFE, because the compiler doesn't have their source code, and all functions that interact with the filesystem have to ultimately call C functions. So, you can't use something like dirEntries with CTFE.

The only way that you can do anything along the lines of reading files during CTFE is to use string imports to insert the text of a file directly into the module.

- Jonathan M Davis



February 11, 2019
On Monday, 11 February 2019 at 00:54:27 UTC, Seb wrote:
> On Monday, 11 February 2019 at 00:19:02 UTC, kdevel wrote:

[...]

> You can't read or list files at compile-time.

dmd can read files at compile time using the import function [1]

> What are you trying to do?

Incorporate HTML template files into a CGI binary. After putting [ and ] around the list in LS this works:

```TemplateStore.d
module TemplateStore;
import std.path;
import std.conv;
import std.file;

immutable string[string] template_map;

static this ()
{
   immutable LS = import (`LS`);
   immutable template_files = mixin(LS);

   static foreach (f; template_files) {
      pragma (msg, `reading template <` ~ f ~ ">");
      template_map[f] = import (f);
   }
}
```

[1] https://forum.dlang.org/thread/njnwacxnvxlwlpjcuyud@forum.dlang.org
February 11, 2019
On Monday, 11 February 2019 at 01:05:05 UTC, kdevel wrote:
> On Monday, 11 February 2019 at 00:54:27 UTC, Seb wrote:
>> On Monday, 11 February 2019 at 00:19:02 UTC, kdevel wrote:
>
> [...]
>
>> You can't read or list files at compile-time.
>
> dmd can read files at compile time using the import function [1]


Sorry, I should have rephrased: you can't call any OS-level functions at compile-time. This includes std.file.read and std.file.dirEntries.