Thread overview
port of redo-c to BetterC
Jun 09
jfondren
6 days ago
aquaratixc
6 days ago
Dennis
6 days ago
aquaratixc
6 days ago
Dennis
6 days ago
aquaratixc
June 09

Good day! This is my first time working with betterC and for the sake of experiment I decided to translate the redo-c implementation (https://github.com/leahneukirchen/redo-c) into BetterC, but I ran into a number of problems:

  1. In the original implementation, there are places where the openat function is used (dir_fd, target, O_RDONLY | O_DIRECTORY); and I couldn't find a replacement. Are there any options where you can get it?
  2. Similarly, the dprintf function was not found, which, as I understand it, is a non-standard extension. Is there a way to add this?
    I will also be glad if someone picks up the idea and brings it to mind. The current version is here: https://github.com/aquaratixc/redo-d/tree/main
June 09

On Wednesday, 9 June 2021 at 21:45:33 UTC, aquaratixc wrote:

>

Good day! This is my first time working with betterC and for the sake of experiment I decided to translate the redo-c implementation (https://github.com/leahneukirchen/redo-c) into BetterC, but I ran into a number of problems:

  1. In the original implementation, there are places where the openat function is used (dir_fd, target, O_RDONLY | O_DIRECTORY); and I couldn't find a replacement. Are there any options where you can get it?
  2. Similarly, the dprintf function was not found, which, as I understand it, is a non-standard extension. Is there a way to add this?
    I will also be glad if someone picks up the idea and brings it to mind. The current version is here: https://github.com/aquaratixc/redo-d/tree/main

https://dlang.org/spec/interfaceToC.html

June 09

On Wednesday, 9 June 2021 at 21:45:33 UTC, aquaratixc wrote:

>
  1. In the original implementation, there are places where the openat function is used (dir_fd, target, O_RDONLY | O_DIRECTORY); and I couldn't find a replacement. Are there any options where you can get it?
  2. Similarly, the dprintf function was not found, which, as I understand it, is a non-standard extension. Is there a way to add this?

In general you can just use the C functions directly, with reference to system
manpages, prior interfaces in D repositories (dmd+phobos+druntime are good
repos to have around), https://dlang.org/spec/interfaceToC.html , and (until
ImportC lands) your system's headers for the right magic numbers.

extern(C) nothrow @nogc int dprintf(int fd, scope const char* format, ...);
extern(C) nothrow @nogc int openat(int dirfd, scope const char *pathname, int flags);
extern(C) nothrow @nogc int openat(int dirfd, scope const char *pathname, int flags, int mode);
extern(C) nothrow @nogc int close(int fd);
import core.sys.posix.fcntl : AT_FDCWD, O_RDONLY;
enum O_DIRECTORY = 0x10000;
import std.stdio : File, write;

void main() {
    int dir, file;
    if (-1 != (dir = openat(AT_FDCWD, "test", O_DIRECTORY | O_RDONLY))) {
        scope(exit) close(dir);
        if (-1 != (file = openat(dir, "x", O_RDONLY))) {
            File f;
            f.fdopen(file, "r");
            write("test/x contained: ", f.readln);
        }
    }
}
6 days ago

Thank you very much to everyone who answered. That helped. I have more questions ... I also ran into this: there is a function redo_ifchange (int targetc, char ** targetv) inside which the char [targetc] skip; array is defined; , and as a result we get an error like redo.d (784): Error: variable `targetc` cannot be read at compile time. it is clear that the compiler cannot define a variable at the compilation stage and set the dimension from it, but how to solve the question in

6 days ago

On Thursday, 10 June 2021 at 09:53:36 UTC, aquaratixc wrote:

>

there is a function redo_ifchange (int targetc, char ** targetv) inside which the char [targetc] skip; array is defined;

That's a Variable-length array which D doesn't support.
If targetc has an upper bound, you can use a static array instead:

import core.stdc.stdlib;

void redo_ifchange (int targetc, char ** targetv) {
    char[4096] buf = void;
    assert(targetc <= buf.length);
    char* skip = buf.ptr;
    // code
}

For larger sizes, you can use heap-allocation:

import core.stdc.stdlib;

void redo_ifchange (int targetc, char ** targetv) {
    char* skip = cast(char*) malloc(targetc * char.sizeof);
    scope(exit) free(skip);
    // code
}

And if you really want variable-size stack allocation, you can use alloca:

import core.stdc.stdlib;

void redo_ifchange (int targetc, char ** targetv) {
    char* skip = cast(char*) alloca(targetc * char.sizeof);
    // code
}

Though I don't recommend it.

6 days ago

On Thursday, 10 June 2021 at 10:04:38 UTC, Dennis wrote:

>

On Thursday, 10 June 2021 at 09:53:36 UTC, aquaratixc wrote:

>

there is a function redo_ifchange (int targetc, char ** targetv) inside which the char [targetc] skip; array is defined;

That's a Variable-length array which D doesn't support.
If targetc has an upper bound, you can use a static array instead:

import core.stdc.stdlib;

void redo_ifchange (int targetc, char ** targetv) {
    char[4096] buf = void;
    assert(targetc <= buf.length);
    char* skip = buf.ptr;
    // code
}

For larger sizes, you can use heap-allocation:

import core.stdc.stdlib;

void redo_ifchange (int targetc, char ** targetv) {
    char* skip = cast(char*) malloc(targetc * char.sizeof);
    scope(exit) free(skip);
    // code
}

And if you really want variable-size stack allocation, you can use alloca:

import core.stdc.stdlib;

void redo_ifchange (int targetc, char ** targetv) {
    char* skip = cast(char*) alloca(targetc * char.sizeof);
    // code
}

Though I don't recommend it.

Thanks. Its really helpful. However, as I said, there are still questions: in particular, there is one mistake that I could not resolve. When I try to copy, I get an error like this: redo.o:redo.d:function _D4redo13redo_ifchangeFiPPaZv: error: undefined reference to '_D4core3sys5posixQk4wait9WIFEXITEDFNaNbNiNfiZb' redo.o:redo.d:function _D4redo13redo_ifchangeFiPPaZv: error: undefined reference to '_D4core3sys5posixQk4wait11WEXITSTATUSFNaNbNiNfiZi' collect2: although i imported core.sys.posix.sys.wait

6 days ago

On Thursday, 10 June 2021 at 10:23:00 UTC, aquaratixc wrote:

>

Thanks. Its really helpful. However, as I said, there are still questions: in particular, there is one mistake that I could not resolve. When I try to copy, I get an error like this: redo.o:redo.d:function _D4redo13redo_ifchangeFiPPaZv: error: undefined reference to '_D4core3sys5posixQk4wait9WIFEXITEDFNaNbNiNfiZb' redo.o:redo.d:function _D4redo13redo_ifchangeFiPPaZv: error: undefined reference to '_D4core3sys5posixQk4wait11WEXITSTATUSFNaNbNiNfiZi' collect2: although i imported core.sys.posix.sys.wait

WIFEXITED and WEXITSTATUS are C macros that druntime translates to D functions.
Importing only means you expect it to be there at link-time. When compiling with -betterC, you don't actually link druntime usually. I think it's easiest to just copy-paste those function definitions from druntime to your own source instead of importing them. Or you can compile with optimizations (e.g. -inline for dmd, -O1 for GDC/LDC) and hope the functions get inlined.

6 days ago
On 6/10/21 7:21 AM, Dennis wrote:
> On Thursday, 10 June 2021 at 10:23:00 UTC, aquaratixc wrote:
>> Thanks. Its really helpful. However, as I said, there are still questions: in particular, there is one mistake that I could not resolve. When I try to copy, I get an error like this: ```
>> redo.o:redo.d:function _D4redo13redo_ifchangeFiPPaZv: error: undefined reference to '_D4core3sys5posixQk4wait9WIFEXITEDFNaNbNiNfiZb'
>> redo.o:redo.d:function _D4redo13redo_ifchangeFiPPaZv: error: undefined reference to '_D4core3sys5posixQk4wait11WEXITSTATUSFNaNbNiNfiZi'
>> collect2: ``` although i imported ```core.sys.posix.sys.wait```
> 
> WIFEXITED and WEXITSTATUS are C macros that druntime translates to D functions.
> Importing only means you expect it to be there at link-time. When compiling with `-betterC`, you don't actually link druntime usually. I think it's easiest to just copy-paste those function definitions from druntime to your own source instead of importing them. Or you can compile with optimizations (e.g. `-inline` for dmd, `-O1` for GDC/LDC) and hope the functions get inlined.

Hm... those probably should be marked pragma(inline, true), but I'm not sure if that will be a complete fix.

-Steve
6 days ago

Thank you all for your help. I translated the program, and it seems I even collected it with the help of the LDC. I understand the reasons for Segfault, the project is here: https://github.com/aquaratixc/redo-d/blob/main/redo.d