Is it possible to run a single unittest without an external library?

2021-05-09 Thread Anthony via Digitalmars-d-learn

Hello,

I'm trying to setup a minimal testing process with unittest.
However, I would like to run the tests of a single file to keep 
things fast.
At the moment,  it runs all unittests that are imported with a 
file.

eg.
`rdmd -I... source/foo.d` will run unittests bar.d if it is 
imported into foo.d


Is there a way to run the unittests in a single file via rdmd?
I couldn't find the relevant command line flags and was hoping I 
missed something or theres some sort of trick I could use.


Re: How do I run multiple unittests with rdmd?

2021-03-04 Thread Anthony via Digitalmars-d-learn

On Friday, 5 March 2021 at 02:08:37 UTC, H. S. Teoh wrote:
In the latter case, you could just use `rdmd -unittest -i -run 
main.d` (replace `main.d` with whatever source file contains 
main()) to automatically compile all modules including their 
unittests *and* run 'em all in one shot.


I didn't know that. Good to know. Thanks


Only in the former case would you need to use your `find` 
pipeline above. :-)


I should have mentioned, this is for a library that is used by 
multiple applications.

So I guess the find pipeline is the way to go then.


How do I run multiple unittests with rdmd?

2021-03-04 Thread Anthony via Digitalmars-d-learn

Hello,

I'm trying to run multiple unittest files with rdmd.
So far I use `find` to just pipe in the files. Eg:


time find source -name *__tests.d -exec rdmd -unittest --main 
-I../libprelude/source -I../libparser/source 
-I../libgeometry/source -Isource {} \;


Is there an easier way to do this?


Re: tiny alternative to std library

2021-03-03 Thread Anthony via Digitalmars-d-learn

On Wednesday, 3 March 2021 at 07:23:58 UTC, Siemargl wrote:
On Wednesday, 3 March 2021 at 03:52:13 UTC, Anthony Quizon 
wrote:

On Monday, 1 March 2021 at 08:52:35 UTC, Imperatorn wrote:

Having a library with bare minimum meta programming would help 
with this I think. I'm willing to pay the cost of safety.

Strange, usual D programs builds fast.

As a alternative to Phobos, you can see to D1 standard library 
- Tango, ported to D2.

https://github.com/SiegeLord/Tango-D2

Without mass template magic, its easier.

There is also print book "Learn to Tango with D".


Thanks! I'll take a look.


Strange, usual D programs builds fast.


What build times do you get?

Seems like some other people have similar issues:
https://forum.dlang.org/post/pvseqkfkgaopsnhqe...@forum.dlang.org
https://forum.dlang.org/thread/mailman.4286.1499286065.31550.digitalmar...@puremagic.com



tiny alternative to std library

2021-02-25 Thread Anthony via Digitalmars-d-learn

Hello,

I noticed that importing some std libraries causes the build time 
to jump to around 1 - 3 secs.


I started creating my own helper functions to avoid importing std 
for scripting and prototyping in order to keep the compile time 
at around 0.5 secs.


I was wondering if anyone knows of any libraries that are geared 
towards something like this?


Thanks


Re: How do I compose pipes?

2021-01-28 Thread Anthony via Digitalmars-d-learn

On Friday, 29 January 2021 at 03:49:38 UTC, Ali Çehreli wrote:

On 1/28/21 3:45 PM, Anthony wrote:

> void end(AccumulatorPipe acc) {
>  auto pids = acc.pids ~ P.spawnShell("cat", acc.stdout);
>
>  foreach (pid; pids) {
>  P.wait(pid);
>  }
> }
> ```
>
>
> So now I can do something like:
> ```
> run("find source -name '*.d'")
>  .pipe("entr ./make.d tests")
>  .end(),

Cool but there should be one improvement because I don't think 
end() is guaranteed to be executed in that code, which may 
leave zombie processes around. From 'man waitpid':


  "A child that terminates, but has not been waited for becomes 
a "zombie".


Which is relayed to std.process documentation as "to avoid 
child processes becoming "zombies"".


Ali


I take it you're referring to missing scope guards like in your 
code

`scope (exit) wait(lsPid);`

Yeah, that is a tricky one. I can't think of a way to have a nice 
interface that also closes the pids on exit since scope guards 
are handled on function exit in this case.


Perhaps thats just the nature of the problem though.

I'll take a look at what scriptlike does 
https://github.com/Abscissa/scriptlike#script-style-shell-commands


Re: How do I compose pipes?

2021-01-28 Thread Anthony via Digitalmars-d-learn

On Thursday, 28 January 2021 at 17:18:46 UTC, Ali Çehreli wrote:

On 1/28/21 2:16 AM, Anthony wrote:

> auto p = pipeProcess("ls");
> auto q = pipeProcess("cat", stdin = p.stdout); //it would be
good to do

That would work if `cat` received the *contents* of the files 
(and with a "-" command line switch). Since `ls` produces file 
names, you would have to make the complete `cat` command line 
from `ls`'s output.


> Do I need to manually extract the output from
pipes.stdin.readln

Seems to be so for the `ls | cat` case. But the following `find 
| grep` example shows how two ends of pipes can be connected:


import std.stdio;
import std.process;
import std.range;

// BONUS: Enable one of the following lines to enjoy an issue.
// version = bonus_bug;
// version = bonus_bug_but_this_works;

void main() {
  // Writes to 'a':
  auto a = pipe();
  auto lsPid = spawnProcess([ "find", "."], stdin, a.writeEnd);
  scope (exit) wait(lsPid);

  // Reads from 'a', writes to 'b':
  auto b = pipe();
  auto catPid = spawnProcess([ "grep", "-e", `\.d$` ], 
a.readEnd, b.writeEnd);

  scope (exit) wait(catPid);

  version (bonus_bug) {
// Fails with the following error.
//
// "/usr/include/dmd/phobos/std/typecons.d(6540): Error:
// `"Attempted to access an uninitialized payload."`"
writefln!"Some of the D source files under the current 
directory:\n%-(  %s\n%)"(

  b.readEnd.byLine);

  } else version (bonus_bug_but_this_works) {
// Note .take at the end:
writefln!"Some of the D source files under the current 
directory:\n%-(  %s\n%)"(

  b.readEnd.byLine.take(1000));

  } else {
// The results are read from 'b':
writeln(b.readEnd.byLine);
  }
}

I've discovered a strange issue, which can be observed by 
uncommenting the 'version = bonus_bug;' line above. But comment 
that one back in and uncomment the next line, now it works. (?)


Ali



Thanks Ali.
I was messing around and below seems to work well enough for me.

```

struct AccumulatorPipe {
Pid[] pids;

File stdin;
File stdout;
}

AccumulatorPipe run(string cmd) {
AccumulatorPipe acc;

auto p = P.pipeShell(cmd, P.Redirect.stdout);

acc.pids ~= p.pid;
acc.stdout = p.stdout;

return acc;
}

AccumulatorPipe pipe(AccumulatorPipe acc0, string cmd) {
AccumulatorPipe acc;
Pipe p = P.pipe();

acc.stdin = p.writeEnd;
acc.stdout = p.readEnd;

auto pid = P.spawnShell(cmd, acc0.stdout, acc.stdin);
acc.pids = acc0.pids ~ pid;

return acc;
}

void end(AccumulatorPipe acc) {
auto pids = acc.pids ~ P.spawnShell("cat", acc.stdout);

foreach (pid; pids) {
P.wait(pid);
}
}
```


So now I can do something like:
```
run("find source -name '*.d'")
.pipe("entr ./make.d tests")
.end(),
```


That would work if `cat` received the *contents* of the files 
(and with a "-" command line switch)


I was actually trying to use cat to just spit out the filenames 
of the directory as a test.

But I see what you mean.



How do I compose pipes?

2021-01-28 Thread Anthony via Digitalmars-d-learn
This post https://dlang.org/library/std/process/pipe.html 
mentions:


Pipes can, for example, be used for interprocess communication 
by spawning a new process and passing one end of the pipe to the 
child, while the parent uses the other end. (See also 
pipeProcess and pipeShell for an easier way of doing this.)


```
auto p = pipe();
auto outFile = File("D downloads.txt", "w");
auto cpid = spawnProcess(["curl", 
"http://dlang.org/download.html;],

 stdin, p.writeEnd);
scope(exit) wait(cpid);
auto gpid = spawnProcess(["grep", "-o", `http://\S*\.zip`],
 p.readEnd, outFile);
scope(exit) wait(gpid);
```

How am I able to compose the pipes from pipeProcess if I can't 
pass in an existing pipe into the function. Eg.


```
auto p = pipeProcess("ls");
auto q = pipeProcess("cat", stdin = p.stdout); //it would be good 
to do this or something like it

```

Do I need to manually extract the output from pipes.stdin.readln 
and place it in pipes.stdout.writeln?

Or is there an easier way to do this?

Thanks


Re: How do I get the output of the time bash command?

2021-01-27 Thread Anthony via Digitalmars-d-learn

On Wednesday, 27 January 2021 at 09:58:18 UTC, Arafel wrote:

On 27/1/21 10:35, Anthony wrote:


I'm trying to read the timed output of a pipeShell command but 
it only results in empty output.


Does anyone know why this is?


```
     auto p = pipeShell("time ls");

     foreach(str; p.stdout.byLine) {
     writefln("%s",str);
     }
```


I'm not sure why you get an empty output, you should get at 
least the `ls` output unless it's an empty directory (or one 
with only "dot" files).


However, in any case `time` returns the timing information 
through `stderr`, not `stdout`[1]. You can try [2,3] (untested):


```
auto p = pipeShell("time ls", Redirect.stderrToStdout);
```

Best,

A.

[1]: https://linux.die.net/man/1/time
[2]: https://dlang.org/library/std/process/pipe_shell.html
[3]: https://dlang.org/library/std/process/redirect.html


Thanks! I think this was the issue.
Turns out that pipeShell uses sh not bash so the "time" program 
isn't available.

When I printed stderr, it showed me the error.


How do I get the output of the time bash command?

2021-01-27 Thread Anthony via Digitalmars-d-learn



I'm trying to read the timed output of a pipeShell command but it 
only results in empty output.


Does anyone know why this is?


```
auto p = pipeShell("time ls");

foreach(str; p.stdout.byLine) {
writefln("%s",str);
}
```


Generating struct members from c structs

2020-07-01 Thread Anthony via Digitalmars-d-learn
When doing interop with a c library, is there a way to 
automatically generate the fields that are needed for a struct?


For example, when interfacing with the lwan c library:

// lwan.h
struct lwan {
struct lwan_trie url_map_trie;
struct lwan_connection *conns;
struct lwan_strbuf headers;

struct {
pthread_barrier_t barrier;
struct lwan_thread *threads;
unsigned int max_fd;
unsigned int count;
} thread;

struct lwan_config config;
struct coro_switcher switcher;

int main_socket;

unsigned int n_cpus;
};

module lwan;

extern (C) {
struct lwan {
  ... // <<< How do I populate this without having to write 
all the sub structs?

};
void lwan_init(lwan* l);
void lwan_shutdown(lwan* l);
}

import lwan;

void main() {
  lwan l; //This is currently not allocating enough memory
  lwan_init();
  lwan_shutdown();
}

How do I populate the lwan struct without having to write all the 
sub structs?


I'm thinking that maybe it'll be best to create a wrapper c 
function that initializes the lwan struct and returns a pointer.


That way I don't have to declare any fields.

extern (C) {
struct lwan;

lwan* lwan_make(); //wrapper function (perhaps in wrapper.c)
void lwan_cleanup(lwan* l); //wrapper function

void lwan_init(lwan* l);
void lwan_shutdown(lwan* l);
}

Is there an easier way though?



Re: Program exited with code -11 when calling

2020-07-01 Thread Anthony via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 05:47:16 UTC, Anthony wrote:

On Wednesday, 1 July 2020 at 05:33:48 UTC, H. S. Teoh wrote:
On Wed, Jul 01, 2020 at 05:04:28AM +, Anthony via 
Digitalmars-d-learn wrote: [...]

auto str_utf8 = str.toUTF8();
bson_error_t error

auto bson = bson_new_from_json(cast(const 
uint8_t*)str_utf8.ptr, -1,

);


I get a "Program exited with code -11" message.
Does anyone know what I'm doing wrong?


D strings are generally not null-terminated (except for 
literals). Before passing them to a C function you need to add 
a trailing null. Try using std.conv.toStringz instead of 
casting the pointer yourself.



T


Thanks H. S. Teoh.
Hmm, still same result though.


import std.string;

auto str = toStringz("{\"a\":1}");

bson_error_t error;

bson_new_from_json(str, -1, );




extern(C) {
...
bson_t* bson_new_from_json(const char* data, long len, 
bson_error_t* error);

}


Noob mistake:
I declared an array that should be of fixed size.

struct bson_error_t {

char[] message;
};

Should be:

struct bson_error_t {

char[504] message;
};

:/


Re: Program exited with code -11 when calling

2020-06-30 Thread Anthony via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 05:33:48 UTC, H. S. Teoh wrote:
On Wed, Jul 01, 2020 at 05:04:28AM +, Anthony via 
Digitalmars-d-learn wrote: [...]

auto str_utf8 = str.toUTF8();
bson_error_t error

auto bson = bson_new_from_json(cast(const 
uint8_t*)str_utf8.ptr, -1,

);


I get a "Program exited with code -11" message.
Does anyone know what I'm doing wrong?


D strings are generally not null-terminated (except for 
literals). Before passing them to a C function you need to add 
a trailing null. Try using std.conv.toStringz instead of 
casting the pointer yourself.



T


Thanks H. S. Teoh.
Hmm, still same result though.


import std.string;

auto str = toStringz("{\"a\":1}");

bson_error_t error;

bson_new_from_json(str, -1, );




extern(C) {
...
bson_t* bson_new_from_json(const char* data, long len, 
bson_error_t* error);

}


Re: Linking D with C structs

2020-06-30 Thread Anthony via Digitalmars-d-learn

On Monday, 29 June 2020 at 10:44:16 UTC, kinke wrote:

On Monday, 29 June 2020 at 06:29:38 UTC, Anthony wrote:

What does "__initZ" refer to?
Does this refer to automatic initialization like "this()"?


Almost, it's the static initializer for that struct, which is 
omitted because you apparently don't compile/link the module 
containing the struct declaration. Initialize the char array 
with zeros (= 0) to make the struct fully zero-initialized, 
preventing the need for that symbol. chars in D are initialized 
with 0xFF, unlike byte and ubyte.


Thanks for this!

What do you mean by "which is omitted because you apparently 
don't compile/link the module containing the struct declaration"?


Is there a link step that I'm missing that will make things 
easier for me?
Is there a way to have D automatically get the struct from the c 
files directly?




Re: Program exited with code -11 when calling

2020-06-30 Thread Anthony via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 05:09:47 UTC, Cym13 wrote:

On Wednesday, 1 July 2020 at 05:04:28 UTC, Anthony wrote:

I'm trying to convert this c function:

bson_t *bson_new_from_json (const uint8_t *data, ssize_t len, 
bson_error_t *error);



Into a D function. This is my attempt:
extern(C) {
struct bson_t;
struct bson_error_t;

bson_t* bson_new_from_json(const uint8_t* data, long len, 
bson_error_t* error);

}

However when I try it, for example:

auto str_utf8 = str.toUTF8();
bson_error_t error

auto bson = bson_new_from_json(cast(const 
uint8_t*)str_utf8.ptr, -1, );



I get a "Program exited with code -11" message.
Does anyone know what I'm doing wrong?

Thanks


I don't know the exact function you are trying to use, but -11 
means "segmentation fault" on linux. This means that your 
program is trying to read or write a memory location that it is 
not supposed to. This typically happens during buffer overflows 
and similar memory corruption bugs.


One thing that jumps to me is the -1 in your call instead of 
the length. Without knowing the C function's implementation I 
would expect it to mean either "read before the array" which 
would be a buffer overflow or to have the special meaning of 
"deduce the string size yourself". In that last case I would 
expect bson_new_from_json to expect a NUL-terminated array, but 
I don't know if your UTF8 array is NUL-terminated.



Thanks for getting back to me.

Yeah I figured it was a segmentation fault, however, I don't know 
exactly how to pinpoint where this is happening. I'm wondering if 
there's anything wrong with how I'm casting the data since 
everything is self contained (assuming bson_new_from_json is 
correct since it works using c directly).


void foo() {
import std.utf;
import core.stdc.stdint;

auto str_utf8 = "{\"a\":1}";
bson_error_t error;

bson_new_from_json(cast(uint8_t*)str_utf8, 
(cast(uint8_t[])str_utf8).length, );

}



Re -1 in the call: Apparently it uses strlen() to deduce the 
size. However, I tried explicitly state the array length but had 
no luck.





Program exited with code -11 when calling

2020-06-30 Thread Anthony via Digitalmars-d-learn

I'm trying to convert this c function:

bson_t *bson_new_from_json (const uint8_t *data, ssize_t len, 
bson_error_t *error);



Into a D function. This is my attempt:
extern(C) {
struct bson_t;
struct bson_error_t;

bson_t* bson_new_from_json(const uint8_t* data, long len, 
bson_error_t* error);

}

However when I try it, for example:

auto str_utf8 = str.toUTF8();
bson_error_t error

auto bson = bson_new_from_json(cast(const uint8_t*)str_utf8.ptr, 
-1, );



I get a "Program exited with code -11" message.
Does anyone know what I'm doing wrong?

Thanks



Linking D with C structs

2020-06-29 Thread Anthony via Digitalmars-d-learn

Hello,


I'm trying to hand write some bindings to mongo-c-driver. (For 
learning purposes and to get the latest bindings).


My binding code to convert  to mongoc/mongoc.d 
is:


= c interop file 
module mongoc/mongoc.d;
import core.stdc.stdint;

extern (c) {
struct {
uint domain;
uint code;
char[504] message; //when this exists, the code does not 
compile

}
}
===

= build script 

export 
LD_LIBRARY_PATH=mongo-c-driver/cmake-build/src/libmongoc:mongo-c-driver/cmake-build/src/libbson:$LD_LIBRARY_PATH


dmd hello_mongo.d \
-I=mongo-c-driver/src/libmongoc/src/ \
-I=mongo-c-driver/src/libbson/src/ \
-I=mongo-c-driver/cmake-build/src/libbson/src/bson/ \
-I=mongo-c-driver/cmake-build/src/libmongoc/src/mongoc \
-L=-Lmongo-c-driver/cmake-build/src/libmongoc \
-L=-Lmongo-c-driver/cmake-build/src/libbson \
-L=-lmongoc-1.0 \
-L=-lbson-1.0 \

./hello_mongo



However, when I add the message field in the struct, I cannot 
compile the code:


ld: hello_mongo.o: in function `_Dmain':
hello_mongo.d:(.text._Dmain[_Dmain]+0x1a): undefined reference to 
`_D6mongoc6mongoc13_bson_error_t6__initZ'



What does "__initZ" refer to?
Does this refer to automatic initialization like "this()"?