www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Read files at compile time

reply Henrik <zodiachus gmail.com> writes:
Hello! 

I have a question or two regarding what is allowed to be executed at compile
time and not. Consider the following:

<code>
import std.stdio;
import std.file;
import std.string;


char[][] loadArchetypes( char[] fileName )
{
    char[][] archetypes = splitlines( cast(char[])read( fileName ) );

    return archetypes;
}


void main()
{
    /// Load archetypes
    const char[][] archetypes = loadArchetypes( "archetypes.txt" );

    foreach( archetype; archetypes )
    {
        writefln( archetype );
    }
}

</code>


I suspect that I am not allowed to do this for some reason. I get the very
unhelpful error:
Compiling: fileTest.d
Error: variable useWfuncs is used before initialization
Process terminated with status 1 (0 minutes, 0 seconds)
0 errors, 0 warnings


Is it possible to read a file at compile-time in the manner I am trying to do?
What does the error message mean?


Yours most confusedly,

Henrik
May 31 2007
next sibling parent Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
Henrik wrote:
 Is it possible to read a file at compile-time in the manner I am trying to do?

Using splitlines() won't work: it allocates memory, which makes it ineligible for CTFE. It probably does other disallowed stuff, too. You can use import expressions to read the file into a char[], but splitting on lines at compile time is a bit trickier. You'll need to write a template to do the split.
May 31 2007
prev sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Hi Henrik,

Check out http://www.digitalmars.com/d/expression.html#ImportExpression , which
can read files in as compile-time string literals. You'd then need to write a
CTFE-compliant string-splitting function and mix that back in. So, you'd have:

mixin(ctfe_split("archetypes", import("file.txt")));

Which should become something like:

char[][3] archetypes = [ "foo", "bar", "baz", ];

Writing the function itself shouldn't be _too_ hard, but there are a number of
constructs which make it unable to be executed at compile-time, so ensure it
has no side effects.

Regards,
Fraser

Henrik Wrote:

 Hello! 
 
 I have a question or two regarding what is allowed to be executed at compile
time and not. Consider the following:
 
 <code>
 import std.stdio;
 import std.file;
 import std.string;
 
 
 char[][] loadArchetypes( char[] fileName )
 {
     char[][] archetypes = splitlines( cast(char[])read( fileName ) );
 
     return archetypes;
 }
 
 
 void main()
 {
     /// Load archetypes
     const char[][] archetypes = loadArchetypes( "archetypes.txt" );
 
     foreach( archetype; archetypes )
     {
         writefln( archetype );
     }
 }
 
 </code>
 
 
 I suspect that I am not allowed to do this for some reason. I get the very
unhelpful error:
 Compiling: fileTest.d
 Error: variable useWfuncs is used before initialization
 Process terminated with status 1 (0 minutes, 0 seconds)
 0 errors, 0 warnings
 
 
 Is it possible to read a file at compile-time in the manner I am trying to do?
What does the error message mean?
 
 
 Yours most confusedly,
 
 Henrik

May 31 2007
parent Henrik <zodiachus gmail.com> writes:
Robert Fraser Wrote:

 Hi Henrik,
 
 Check out http://www.digitalmars.com/d/expression.html#ImportExpression ,
which can read files in as compile-time string literals. You'd then need to
write a CTFE-compliant string-splitting function and mix that back in. So,
you'd have:
 
 mixin(ctfe_split("archetypes", import("file.txt")));
 
 Which should become something like:
 
 char[][3] archetypes = [ "foo", "bar", "baz", ];

Looks like it could be messy, but worth a try :) There's not a lot of static information that I want to embed at the moment, but there will be more in the future. It would be nice to be able to avoid large chunks of embedded text/data in the source code by appending it at compile time.
May 31 2007