Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Simple Header to D Source Converter Example

Part of TutorialAdvanced

Description

This simple program tries to convert a simple header (.h) file to a D source (.d) file. This can be useful for dealing with resource scripts (.rc) which can be complied into resources files (.res) that can be combined with executables (.exe).

Example

simpleheadertodsrcexample.d

module tutorials.examples.h_to_d.simpleheadertodsrcexample;

/*

SimpleHeaderToDsrcExample
by J C Calvarese

License: Public Domain

Partially converts a C header file (.h) to a D module (.d).
 * Doesn't convert everything.
 * Converts constants so that I can use them in a resource file and in a D module.
 * End-of-line comments (//) aren't handled as they should be.

*/



import std.file;
import std.stream;
import std.string;
import std.stdio;


const char[] pgmFilename = "SimpleHeaderToDsrcExample.exe";


char[] BaseFilenameWithPath(char[] r)
{

    /* Returns the path & filename without the .h extension. */

    int i;
    char[] s;

    i = rfind(r, ".h");

    if (i > 0) s = r[0..i];
    else s = r;

    return s;
}



int main(char[][] Args)
{
    char[] r;
    char[] v1;
    char[] v2;
    char[] s1;
    char[] s2;

    int i;
    int line;

    writefln(pgmFilename ~ " (partially converts .h files to .d files)");

    if (Args.length < 2) 
    { 
		printf("Usage: " ~ pgmFilename ~ " [source.h]\n");	
		return 0;
    }

    if (exists(Args[1])) /* File Exists . . . */
    {
		writefln(pgmFilename ~ ": Creating " ~ BaseFilenameWithPath(Args[1]) ~ ".d...");
	
        File fi = new File(Args[1]);

        File fo = new File(); 
        fo.create(BaseFilenameWithPath(Args[1]) ~ ".d");

        while (!fi.eof())  
        {
            r = strip(fi.readLine());
            line++;
            if (r.length >= 0) 
            {
                /* split varName into name & value */
                i = find(r, ' ');  /* returns -1 if it's not found . . . */

                if (i > 0)
                {
                    s1 = strip(r[0..i]);
                    s2 = strip(r[i..r.length]);
    
                    if(s1 == "#define")
                    {        
                        i = find(s2, ' ');
    
                        if (i == 0)
                            printf("Error (line %i): missing definition.", line);
                        else
                        {
                            v1 = strip(s2[0..i]);
                            v2 = strip(s2[i..s2.length]);
                           
                            if (v2[0..1] == "\"")
                            {
                                fo.writeLine("const char[] " ~ v1 ~ " = " ~ v2 ~ ";");
                            }
                            else
                                if (v2[0..1] == "-")
                                {
                                    fo.writeLine("const int " ~ v1 ~ " = " ~ v2 ~ ";");
                                }
                                else
                                {
                                    fo.writeLine("const uint " ~ v1 ~ " = " ~ v2 ~ ";");
                                }
                        }
                    }
                    else fo.writeLine(r);
                }    
                else fo.writeLine("");
            }
        }

        writefln("h_to_d.exe: Finished.");
        fo.close();
        fi.close();
    }
    else
        writefln("File not found: %i", Args[1]);
    return 0;
}

Compiling

Run the batch file (build.bat) to compile and test the example.

To see what the resource scripts actually do, you'll need to have the "rcc" program install (available for free from the Digital Mars "Basic Utilities" package from: http://www.digitalmars.com/download/dmcpp.html).

Tested Version

Tested with DMD v0.143.

Other helpful files

bulid.bat

@echo off
echo Building SimpleHeaderToDsrcExample...
dmd SimpleHeaderToDsrcExample.d -O -I..\..\..
echo Compilation complete.
pause
erase SimpleHeaderToDsrcExample.obj
erase SimpleHeaderToDsrcExample.map
echo.

echo Testing SimpleHeaderToDsrcExample...
SimpleHeaderToDsrcExample.exe Standard.h
pause
type standard.d
erase standard.d
echo.

echo Testing SimpleHeaderToDsrcExample for "File not found"...
SimpleHeaderToDsrcExample.exe Not_Standard.h
pause
echo.

rem  The "rcc" program is from the Digital Mars "Basic Utilities" package
rem  Download it from: http://www.digitalmars.com/download/dmcpp.html

SimpleHeaderToDsrcExample.exe resource.h
rcc resource.rc -v -32
dmd SimpleHeaderToDsrcExample.d resource.res -I..\..\..
pause
echo.

standard.h

#define pgmTitle            "Program Name"
#define pgmInternalName     "ProgramName"
#define pgmOriginalFilename "ProgramName.exe"

#define pgmFileDescription  "Hopefully it does something"

#define pgmVersion "0.0.1"
#define pgmMajVer  0
#define pgmMinVer  0
#define pgmBuild   1

#define pgmCopyright "(c) 2005 A Nonymous"
#define pgmCompanyName "Software Company"

#define pgmIcon "program.ico"

resource.h

#define pgmTitle            "SimpleHeaderToDsrcExample"
#define pgmInternalName     "SimpleHeaderToDsrcExample"
#define pgmOriginalFilename "SimpleHeaderToDsrcExample.exe"

#define pgmFileDescription  "Converts a simple .h file into a .d file"

#define pgmVersion "0.0.1"
#define pgmMajVer  0
#define pgmMinVer  0
#define pgmBuild   1

#define pgmCopyright "(c) 2005 J C Calvarese"
#define pgmCompanyName "dsource.org"

#define pgmIcon "SimpleHeaderToDsrcExample.ico"

#define ID_ICON 1000

resource.rc

#include "resource.h"

1000 ICON MOVEABLE PURE LOADONCALL DISCARDABLE pgmIcon
1 VERSIONINFO
FILEVERSION    pgmMajVer, pgmMinVer, pgmBuild, 0
PRODUCTVERSION pgmMajVer, pgmMajVer, pgmBuild, 0
FILEOS 0x4
FILETYPE 0x1
BEGIN
BLOCK "StringFileInfo"
BEGIN
	BLOCK "040904B0"
	BEGIN
        VALUE "LegalCopyright", pgmCopyright
        VALUE "FileDescription",  pgmFileDescription
		VALUE "Author", "J C Calvarese"
		VALUE "CompanyName", pgmCompanyName
		VALUE "ProductName", pgmTitle
		VALUE "FileVersion", pgmVersion
		VALUE "ProductVersion", pgmVersion
		VALUE "InternalName", pgmInternalName
		VALUE "OriginalFilename", pgmOriginalFilename
	END
END

BLOCK "VarFileInfo"
BEGIN
	VALUE "Translation", 0x0409,  0x04B0 //0x0409 0x04B0
END
END