I'm confused as to how C structures are imported into Nim. Specifically I'm trying to use the Stat structure of the posix module on FreeBSD and am confused.
The Stat object is defined as being imported from sys/stat.h and contains the fields st_atime, st_mtime and st_ctime which are all of type Time. However the definition in sys/stat.h contains the fields st_atim, st_mtim and st_ctim which are all of type struct timespec.
Since I am comparing file modifications times I need access to what the system returns, not a truncated value. Would it be sufficient for me to define my own Stat object mapping to the stat struct as defined on the system, along with the stat system call?
No, it's just that FreeBSD doesn't care about the Posix standard:
time_t st_atime time of last access
time_t st_mtime time of last data modification
time_t st_ctime time of last status change
http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysstat.h.html http://pubs.opengroup.org/onlinepubs/009604499/basedefs/sys/stat.h.html
Would it be sufficient for me to define my own Stat object mapping to the stat struct as defined on the system, along with the stat system call?
Yeah but you could also create a PR patching posix.nim for FreeBSD.
I'm still confused about how the importc pragma works. Does it just do a union of what's defined in the header and how you define the object in Nim, or is there more of a correlation? The strange thing is that it all appears to work here, or at least it compiles and produces a result that at first glance at least seems reasonable. It just lacks the proper nanosecond resolution, which I believe is part of the posix standard.
I would definitely like to get this all working properly on FreeBSD, so once I understand what's going on I can have a go at patching it. We also seem to be be missing the utimensat from posix.
There are a few moving parts here. For the C back end, Nim generated code just uses the struct stat from the C library headers and generates Cvariable.Cmember references.
The C library headers usually define the st_mtim & kin members to be timespec and then define accessor C preprocessor macros st_mtime === st_mtim.st_tv_sec. This "just works" in C, is backward compatible, and allows the structure to not waste space/storage for duplicated fields. The Nim generated C inherits the just working since the CPP macro gets expanded at C compilation time.
There seems no great reason why Nim should not just parallel this construction with the primary data declaration being the "without an 'e'" st_mtim -- except that Mac OSX does NOT have high-resolution file timestamps, one of a great many OSX irregularities.