Misc.
The following code snippets have no direct relation to computing flow fields, etc. but may be of use in constructing a complete program.
Reading initialization files
This is an example of using associative arrays and string parsing in D to initialize non-trivial variables: a vector and a tuple.
import
std.stdio, std.conv, std.regex,
std.typetuple, std.string;
void main()
{
/// open input file
File f;
f.open("input.txt", "r");
/// parse input file
string input[string];
string key, val;
auto lvalFmt = regex(r"^\s*(\w+)\s*=");
auto rvalFmt = regex(r"=\s*(.+)\s*;");
foreach(ref string line; lines(f))
{
auto lval = match(line, lvalFmt);
if(lval.captures.length > 1)
{
auto rval = match(line, rvalFmt);
if(rval.captures.length > 1)
{
/// store entry
key = lval.captures[1];
val = rval.captures[1];
input[key] = val;
}
}
}
/// initialize variables
auto U = new double[3];
TypeTuple!(int, double) quit;
U = parse!(typeof(U))(input["U"]);
auto buf = input["quit"];
foreach(i, T; quit)
{
munch(buf, "[, ]");
quit[i] = parse!(typeof(T))(buf);
}
writeln(U);
writeln([quit]);
}
The input file is written as
U = [1.12, 2, -4.2e-4]; // ref. velocity quit = [1000, 0.001]; // iter. cut-off (max iter, min norm)
Calling a D function from C
This is an example to show how to call D code from C. The first listing shows the C top-level which initializes the D runtime environment and then calls the D function.
#include <stdio.h>
#include <stdlib.h>
struct Data {
int* idx;
int idxLen;
};
char rt_init(long long);
char rt_term(long long);
void procData(struct Data*);
void main() {
int i;
struct Data *data;
data = malloc(sizeof(struct Data));
data->idxLen = 5;
/// call D functions
rt_init(0); /// initialize core.runtime
procData(data);
rt_term(0); /// terminate core.runtime
printf("for [0..%d)\n", data->idxLen);
for (i = 0; i < data->idxLen; ++i) {
printf("-%d^%d = %d\n", i, i, data->idx[i]);
}
}
The second listing shows the D function in which a structure element is allocated and initialized. To link the program, a third file is required which declares an empty D main function. Compilation can be performed with gcc and dmd respectively, then link with gcc using DFLAGS from the dmd.conf file.
import std.stdio, std.c.stdlib;
struct DataCp {
int[] idx;
}
extern (C)
struct Data {
int* idx;
int idxLen;
}
extern (C)
void procData(ref Data data)
{
writeln("entered D function");
/// allocate array
data.idx = cast(typeof(data.idx))
malloc(data.idxLen * (*data.idx).sizeof);
/// initialize elements
for (int i=0; i<data.idxLen; ++i) {
data.idx[i] = i^^i;
}
/// reference array with D array
DataCp dataCp;
dataCp.idx = data.idx[0..data.idxLen];
/// modify elements via D array
foreach (ref e; dataCp.idx) {
e = -e;
}
writeln("exiting D function");
}