Simple c header => Dlang constants using mixins in compile time

Cym13 via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jun 17 04:23:52 PDT 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
     }




More information about the Digitalmars-d-learn mailing list