Thread overview
Simple c header => Dlang constants using mixins in compile time
Jun 17, 2017
Igor Shirkalin
Jun 17, 2017
Igor
Jun 17, 2017
Igor Shirkalin
Jun 17, 2017
Cym13
Jun 17, 2017
Igor Shirkalin
Jun 18, 2017
Seb
Jun 18, 2017
Igor Shirkalin
June 17, 2017
Hello!

I have a simple C header file that looks like:
#define Name1 101
#define Name2 122
....
#define NameN 157

It comes from resource compiler and I need all these constants to be available in my Dlang program in compile time. It seems to me it is possible. I know I can simply write external program (in python, for example) that does it, but it means I should constantly run it after every change before D compilation.

Please, can anyone help to direct me how to realize it?
Thank you in advance!

Igor Shirkalin


June 17, 2017
On Saturday, 17 June 2017 at 10:56:52 UTC, Igor Shirkalin wrote:
> Hello!
>
> I have a simple C header file that looks like:
> #define Name1 101
> #define Name2 122
> ....
> #define NameN 157
>
> It comes from resource compiler and I need all these constants to be available in my Dlang program in compile time. It seems to me it is possible. I know I can simply write external program (in python, for example) that does it, but it means I should constantly run it after every change before D compilation.
>
> Please, can anyone help to direct me how to realize it?
> Thank you in advance!
>
> Igor Shirkalin

Maybe I am not quite understanding what you are asking but can't you just use:

enum Name1 = 101;
enum Name2 = 122;
...
June 17, 2017
On Saturday, 17 June 2017 at 11:10:47 UTC, Igor wrote:
> On Saturday, 17 June 2017 at 10:56:52 UTC, Igor Shirkalin wrote:
>> Hello!
>>
>> I have a simple C header file that looks like:
>> #define Name1 101
>> #define Name2 122
>> ....
>> #define NameN 157
>>
>> It comes from resource compiler and I need all these constants to be available in my Dlang program in compile time. It seems to me it is possible. I know I can simply write external program (in python, for example) that does it, but it means I should constantly run it after every change before D compilation.
>>
>> Please, can anyone help to direct me how to realize it?
>> Thank you in advance!
>>
>> Igor Shirkalin
>
> Maybe I am not quite understanding what you are asking but can't you just use:
>
> enum Name1 = 101;
> enum Name2 = 122;
> ...

No, I need the original header file to be used in other applications (say, resource compiler). Therefore this file is primary. I think some pretty short code can be written in D that use such a file to generate constants (enum Name1 = 101) in compile time.
June 17, 2017
On Saturday, 17 June 2017 at 11:20:53 UTC, Igor Shirkalin wrote:
> On Saturday, 17 June 2017 at 11:10:47 UTC, Igor wrote:
>> On Saturday, 17 June 2017 at 10:56:52 UTC, Igor Shirkalin wrote:
>>> Hello!
>>>
>>> I have a simple C header file that looks like:
>>> #define Name1 101
>>> #define Name2 122
>>> ....
>>> #define NameN 157
>>>
>>> It comes from resource compiler and I need all these constants to be available in my Dlang program in compile time. It seems to me it is possible. I know I can simply write external program (in python, for example) that does it, but it means I should constantly run it after every change before D compilation.
>>>
>>> Please, can anyone help to direct me how to realize it?
>>> Thank you in advance!
>>>
>>> Igor Shirkalin
>>
>> Maybe I am not quite understanding what you are asking but can't you just use:
>>
>> enum Name1 = 101;
>> enum Name2 = 122;
>> ...
>
> No, I need the original header file to be used in other applications (say, resource compiler). Therefore this file is primary. I think some pretty short code can be written in D that use such a file to generate constants (enum Name1 = 101) in compile time.

I'm sure others will have cleaner solutions as as a quick hack you can read the file at compile time, modify it, and compile the D code on the go:

    import std.stdio;
    import std.array;
    import std.algorithm;

    // Normal function that takes a list of #define and transforms them in enum
    // constants textually.
    string enumify(string header) {
        return header.split("\n")
                     .filter!(x => x.startsWith("#define Name"))
                     .map!(x => x.split(" "))
                     .map!(s => "enum " ~ s[1] ~ " = " ~ s[2] ~ ";")
                     .join("\n");
    }

    unittest {
        string txt = "#define Name1 101\n#define Name2 122";
        assert(txt.enumify == "enum Name1 = 101;\nenum Name2 = 122;");
    }

    /* Our file header.h
    #define Name1 101
    #define Name2 122
    #define Name3 157
    */

    // We import the content of the file, enumify it producing D code, and mix it
    // in place to declare our constants.
    //
    // The string import requires compiling with -Jpath/to/dir/with/header.h
    mixin(enumify(import("header.h")));

    void main(string[] args) {
        writeln(Name3);     // 157 // Yep, that works
        pragma(msg, Name2); // 122 // Yep, that works at compile time too
    }


June 17, 2017
On Saturday, 17 June 2017 at 11:23:52 UTC, Cym13 wrote:
> On Saturday, 17 June 2017 at 11:20:53 UTC, Igor Shirkalin wrote:
>> [...]
>
> I'm sure others will have cleaner solutions as as a quick hack you can read the file at compile time, modify it, and compile the D code on the go:
>
> [...]

Thanks a lot! That what I was looking for.
June 18, 2017
On Saturday, 17 June 2017 at 11:27:40 UTC, Igor Shirkalin wrote:
> On Saturday, 17 June 2017 at 11:23:52 UTC, Cym13 wrote:
>> On Saturday, 17 June 2017 at 11:20:53 UTC, Igor Shirkalin wrote:
>>> [...]
>>
>> I'm sure others will have cleaner solutions as as a quick hack you can read the file at compile time, modify it, and compile the D code on the go:
>>
>> [...]
>
> Thanks a lot! That what I was looking for.

FWIW there are tools for this as well,e.g.

https://github.com/jacob-carlborg/dstep

June 18, 2017
On Sunday, 18 June 2017 at 16:02:38 UTC, Seb wrote:
> On Saturday, 17 June 2017 at 11:27:40 UTC, Igor Shirkalin wrote:
>> On Saturday, 17 June 2017 at 11:23:52 UTC, Cym13 wrote:
>>> On Saturday, 17 June 2017 at 11:20:53 UTC, Igor Shirkalin wrote:
>>>> [...]
>>>
>>> I'm sure others will have cleaner solutions as as a quick hack you can read the file at compile time, modify it, and compile the D code on the go:
>>>
>>> [...]
>>
>> Thanks a lot! That what I was looking for.
>
> FWIW there are tools for this as well,e.g.
>
> https://github.com/jacob-carlborg/dstep

Thank you. I try to do it myself for learning purposes.