nitralime | 2 Mar 19:00 2011

A question about arrays and enums

Hi folks!

Hopefully here is the right place to ask CFFI user related questions.
What would be an appropriate CFFI definition for the following C entities?

1) typedef enum {
       a = 0x01,
       b = 0x02,
       c = a | b,
       d = 0x04 | c
   } test;

2) typedef char XXX[8];

How are the C arrays handled in CFFI?

Any feedback is very much appreciated!

Regards
Nik
_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Luís Oliveira | 7 Mar 11:14 2011
Picon

Re: A question about arrays and enums

Hello Nik,

On Mar 2, 2011 6:01 PM, "nitralime" <nitralime <at> googlemail.com> wrote:
> Hopefully here is the right place to ask CFFI user related questions.
> What would be an appropriate CFFI definition for the following C entities?
>
> 1) typedef enum {
>        a = 0x01,
>        b = 0x02,
>        c = a | b,
>        d = 0x04 | c
>    } test;

It's a bit cumbersome to express that with CFFI. Something like
(defcenum (:a 1) ... (:c #.(logior 1 2)) ...).

> 2) typedef char XXX[8];
>
> How are the C arrays handled in CFFI?

There are some array operations such as mem-aref, and you can allocate
them using foreign-alloc. defcstruct supports arrays via :count.
There's also an :array type that will convert C arrays to Lisp arrays,
but it has some limitations and it's
undocumented (see src/types.lisp).

HTH,

--
Luís Oliveira
http://r42.eu/~luis
nitralime | 7 Mar 17:55 2011

Re: A question about arrays and enums

Hello Luis,

Thank you for your reply!
>> (defcenum (:a 1) ... (:c #.(logior 1 2)) ...). My point regarding "enum" definition was actually if it is
possible to write down a definition of enum in CFFI without
breaking the "abstraction". In the body of enum as you see
there is an interdependency between the fields of enum
being defined: the value of c depends on a and b and
the value of d depends on c.

>> but it has some limitations and it's
>> undocumented (see src/types.lisp).

With that CFFI array type "typedef char XXX[8]"
can be translated now as "(defctype XXX (:array :char 8))"!

What are those limitations?

Regards
Nik

On 03/07/2011 11:14 AM, Luís Oliveira wrote:
Hello Nik, On Mar 2, 2011 6:01 PM, "nitralime" <nitralime <at> googlemail.com> wrote:
Hopefully here is the right place to ask CFFI user related questions. What would be an appropriate CFFI definition for the following C entities? 1) typedef enum {        a = 0x01,        b = 0x02,        c = a | b,        d = 0x04 | c    } test;
It's a bit cumbersome to express that with CFFI. Something like (defcenum (:a 1) ... (:c #.(logior 1 2)) ...).
2) typedef char XXX[8]; How are the C arrays handled in CFFI?
There are some array operations such as mem-aref, and you can allocate them using foreign-alloc. defcstruct supports arrays via :count. There's also an :array type that will convert C arrays to Lisp arrays, but it has some limitations and it's undocumented (see src/types.lisp). HTH, -- Luís Oliveira http://r42.eu/~luis

_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Luís Oliveira | 7 Mar 18:08 2011
Picon

Re: A question about arrays and enums

On Mon, Mar 7, 2011 at 4:55 PM, nitralime <nitralime <at> googlemail.com> wrote:
>>> (defcenum (:a 1) ... (:c #.(logior 1 2)) ...).
>
> My point regarding "enum" definition was actually if it is
> possible to write down a definition of enum in CFFI without
> breaking the "abstraction". In the body of enum as you see
> there is an interdependency between the fields of enum
> being defined: the value of c depends on a and b and
> the value of d depends on c.

Yeah. I'm afraid you'd need to do something along the lines of:

    (defconstant +a+ 1)
    (defcenunum (:a #.+a+) (:b #.(frob +a+)))

>>> but it has some limitations and it's
>>> undocumented (see src/types.lisp).
>
> With that CFFI array type "typedef char XXX[8]"
> can be translated now as "(defctype XXX (:array :char 8))"!
>
> What are those limitations?

One of the limitations is that it doesn't do proper memory management
on the array element type, which is not a problem for primitive types
such as :char.

Another limitation is that if you pass a Lisp array via the :array
type to a foreign function that modifies it you won't see any changes
reflected in the Lisp array, as the Lisp/foreign conversion is
currently one-way only.

Cheers,

--

-- 
Luís Oliveira
http://r42.eu/~luis/
Cyrus Harmon | 11 Mar 17:43 2011

Re: [clx-devel] trivial-features, CLX and SBCL mutual incompatibility


The following patch "fixes" CLX such that SBCL (or, more precisely, and SBCL that is configured to have
:little-endian on its *features* list) no longer sees the old-style eval when conditions and makes
clx.asd stop breaking the compilation due to the subsequent style-warning issued by SBCL:

diff -rN -u old-clx/depdefs.lisp new-clx/depdefs.lisp
--- old-clx/depdefs.lisp	2011-03-11 08:31:55.000000000 -0800
+++ new-clx/depdefs.lisp	2011-03-11 08:31:55.000000000 -0800
 <at>  <at>  -141,7 +141,7  <at>  <at> 
 ;;; You must define this to match the real byte order.  It is used by
 ;;; overlapping array and image code.

-#+(or lispm vax little-endian Minima)
+#+(or lispm vax (and (not sbcl) little-endian) Minima)
 (eval-when (eval compile load)
   (pushnew :clx-little-endian *features*))

Any objections to that patch?

thanks,

Cyrus

On Feb 18, 2011, at 1:40 PM, Cyrus Harmon wrote:

> 
> Forgive me if you've heard me rant about this before, but there is a mutual incompatibility between CLX,
trivial-features (which, for me at least, gets pulled in whenever I try to use CFFI) and SBCL. The problem
is that trivial-features puts :little-endian on *features* and CLX has the following code in defdeps.lisp:
> 
> #+(or lispm vax little-endian Minima)
> (eval-when (eval compile load)
>  (pushnew :clx-little-endian *features*))
> 
> These old-style eval-when conditions cause SBCL to issue a warning, which causes ASDF to stop compiling
CLX. There are many workarounds to this, such as loading CLX before CFFI and there are many possible fixes
(such as making SBCL less pedantic or making ASDF not stop on warnings of this kind, etc...) But it seems to
me that either fixing the CLX source code such that it is more tolerant of SBCL's pedantry or,
alternatively, picking less common names for the *features* in trivial-features would be a good thing. I
don't really have a preference, but it would be nice if the CLX and trivial-features maintainers would
play nice with each other such that, at least when using SBCL, one can load trivial-features and then CFFI.
> 
> I'm certainly open to other suggestions, but I've grown tired of working around this particular problem.
> 
> thanks,
> 
> Cyrus
> 
> 
> _______________________________________________
> clx-devel mailing list
> clx-devel <at> common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/clx-devel
Luís Oliveira | 13 Mar 22:14 2011
Picon

Re: [clx-devel] trivial-features, CLX and SBCL mutual incompatibility

On Fri, Mar 11, 2011 at 4:43 PM, Cyrus Harmon <ch-lisp <at> bobobeach.com> wrote:
> The following patch "fixes" CLX such that SBCL (or, more precisely, and SBCL that is configured to have
:little-endian on its *features* list) no longer sees the old-style eval when conditions and makes
clx.asd stop breaking the compilation due to the subsequent style-warning issued by SBCL:

FWIW, SBCL on little-endian MIPS pushes :little-endian to *features*
out of the box.

--

-- 
Luís Oliveira
http://r42.eu/~luis/
nitralime | 23 Mar 18:53 2011

A question about C and Unicode

Hi folks!

I am playing around with a C library and came across
some issues related to unicode in C. In the unicode enabled
version of this C library which implements UCS-2 (i.e. just BMP)
the "unicode character type" is defined in the header file
as follows:
======================================
/*
 * ZAB_CHAR
 * ZAB_UC
 */

#ifdef ZABonAIX
  #if defined(_AIX51) && defined(ZABwith64_BIT)
    #define ZABonAIX_wchar_is_4B
  #else
    #define ZABonAIX_wchar_is_2B
  #endif
#endif

#ifdef ZABonAIX
  #if defined(_AIX51) && defined(ZABwith64_BIT)
    #define ZABonAIX_wchar_is_4B
  #elif defined(ZABccQ)
    #define ZABonAIX_wchar_is_4B
  #else
    #define ZABonAIX_wchar_is_2B
  #endif
#endif

#if defined(ZABonNT)      || \
    defined(ZABonOS400)   || \
   (defined(ZABonOS390) && !defined(_LP64))  || \
    defined(ZABonAIX) && defined(ZABonAIX_wchar_is_2B)
  #define WCHAR_is_2B
#else
  #define WCHAR_is_4B
#endif

#if defined(ZABonLIN) && defined(GCC_UTF16_PATCH)
  #if __GNUC_PREREQ (4,3)
    #include <uchar.h>
    #define ZAB_UC_is_char16
  #endif
#endif

#ifndef ZABwithUNICODE
  #define ZAB_UC_is_1B
  typedef char ZAB_CHAR;
  typedef char ZAB_UC;
#else  /* ZABwithUNICODE */
  #if defined(WCHAR_is_2B)
    #define ZAB_UC_is_wchar
    typedef wchar_t ZAB_CHAR;
    typedef wchar_t ZAB_UC;
  #elif defined(ZAB_UC_is_char16)
    typedef char16_t ZAB_CHAR;
    typedef char16_t ZAB_UC;
  #else
    #define ZAB_UC_is_UTF16_without_wchar
    typedef unsigned short ZAB_CHAR;
    typedef unsigned short ZAB_UC;
  #endif
#endif /* ZABwithUNICODE or not */

/*
 * CFRSDKwith(out)UTF16_LITERALS
 * for CFR SDK applications: controls use of UTF-16
 * literal enabled compilers.
 */
#if defined(CFRSDKwithUTF16_LITERALS)
#elif defined(CFRSDKwithoutUTF16_LITERALS)
  #define ZABwithoutUTF16_LITERALS
#elif defined(WCHAR_is_2B) || \
    defined(ZABonHP_UX) || \
    (defined(ZABonLIN) && defined(__i386__) && defined(__GNUC__) && (__GNUC__<3)) || \
    (defined(ZABonLIN) && defined(GCC_UTF16_PATCH)) || \
    defined(ZABonSUN) || defined(ZABonAIX)
  /* we have literals for UTF-16 */
#else
  #define ZABwithoutUTF16_LITERALS
#endif
======================================
p, li { white-space: pre-wrap; }
All this boils down to

+---------------------------+

+------>-| typedef wchar_t ZAB_CHAR; |

| | typedef wchar_t ZAB_UC; |

| +---------------------------+

|

+---------+ | +----------------------------+

| Unicode |------+------>-| typedef char16_t ZAB_CHAR; |

+---------+ | | typedef char16_t ZAB_UC; |

| +----------------------------+

|

| +----------------------------------+

+------>-| typedef unsigned short ZAB_CHAR; |

| typedef unsigned short ZAB_UC; |

+----------------------------------+


The question is now: Is it correct (resp. safe)
to defctype ZAB_UC just as :uint16 and interpret
it as a UFT-16 code point (with an appropriate endiannness)?

How can the types like wchar_t and char_16_t be defined (resp. used) in CFFI?

Regards
Nik




_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Luís Oliveira | 23 Mar 22:34 2011
Picon

Re: A question about C and Unicode

On Wed, Mar 23, 2011 at 5:53 PM, nitralime <nitralime <at> googlemail.com> wrote:
> +------>-| typedef wchar_t ZAB_CHAR; |
> | | typedef wchar_t ZAB_UC; |

> | Unicode |------+------>-| typedef char16_t ZAB_CHAR; |
> +---------+ | | typedef char16_t ZAB_UC; |

> +------>-| typedef unsigned short ZAB_CHAR; |
> | typedef unsigned short ZAB_UC; |

> The question is now: Is it correct (resp. safe)
> to defctype ZAB_UC just as :uint16 and interpret
> it as a UFT-16 code point (with an appropriate endiannness)?

Maybe. Which typedef applies? This might be a job for cffi-grovel.

> How can the types like wchar_t and char_16_t be defined (resp. used) in
> CFFI?

I'm not sure. You'll have to figure out whether those types are
equivalent to (un)signed short on your platform. Again, cffi-grovel
might help.

--

-- 
Luís Oliveira
http://r42.eu/~luis/

Gmane