On Sat, 2007-09-22 at 14:48 -0700, Erick Tryzelaar wrote:
> According to "man 2 stat" on my mac, the stat struct has this definition:
> 
>      struct stat {
>          dev_t    st_dev;    /* device inode resides on */
>          ino_t    st_ino;    /* inode's number */
>          mode_t   st_mode;   /* inode protection mode */
>          nlink_t  st_nlink;  /* number or hard links to the file */
>          uid_t    st_uid;    /* user-id of owner */
>          gid_t    st_gid;    /* group-id of owner */
>          dev_t    st_rdev;   /* device type, for special file inode */
>          struct timespec st_atimespec;  /* time of last access */
>          struct timespec st_mtimespec;  /* time of last data modification */
>          struct timespec st_ctimespec;  /* time of last file status change */
>          off_t    st_size;   /* file size, in bytes */
>          quad_t   st_blocks; /* blocks allocated for file */
>          u_long   st_blksize;/* optimal file sys I/O ops blocksize */
>          u_long   st_flags;  /* user defined flags for file */
>          u_long   st_gen;    /* file generation number */
>      };
> 
> How should we wrap it? I looked at a couple other languages, and they
> cheat and just use the native (to the language) int to represent
> dev_t, ino_t and etc. Should we follow them in assuming that stat
> can't change in size? That doesn't sound like a very portable idea, so
> do we just detect the size at configure time and do "type dev_t =
> int32" and etc?


This is a good question. Detecting the right sizes in config isn't a 
nice option.

One solution is, for each platform, define the relevant types as
abstract:

        ctypes dev_t, ino_t, mode_t ...;

Then you can make a cstruct, and you are left with the problem
of 'unabstracting' some of the types. For example:

        ctor ulong : u_long = "(unsigned long)$1";
        ctor int : uid_t = "(int)$1";
        ctor ulong : off_t = "(unsigned long)$1";

and now you can access these types with a cast. Choosing a suitable
type for the cast remains a problem. However, the functions should
be the same for all stat records, even Windows .. so you'd probably
want an abstraction layer:

        fun filesize: stat_t -> ulong = 
        | ?st => ulong st.st_size
        ;

This should work on all platforms.

On a related note: I would love to solve the problem:

        #if LINUX
        header '#include <sys/stat.h>';
        #elif WIN32
        header '#include <windows.h>';
        #elif SOLARIS
        header '''
                #include <sys/types.h>
                #include <sys/weird.h>
        ''';
        #endif


        fun stat: string -> stat_t = .. 
                requires stat_h
        ;

Using conditional compilation here is very ugly. A "better" solution
is to use the config/*.fpc mechanism, however that is a target platform
data structure and shouldn't be accessed directly by flxg which
is a host platform tool.

Instead, the notation:

        requires package "stat";

used to bind the run time library binary should also be able
to ensure the right header files are #included. Perhaps
this can be done by:

        #include "application.headers.hpp"

and have this file generated by flx_pkgconfig .. but then
the generated C++ won't compile without running it.. ;(

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to