Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parse-ffi confusion when a type name in a cast is a macro #510

Open
xrme opened this issue Aug 13, 2024 · 0 comments
Open

parse-ffi confusion when a type name in a cast is a macro #510

xrme opened this issue Aug 13, 2024 · 0 comments
Labels

Comments

@xrme
Copy link
Member

xrme commented Aug 13, 2024

Consider this fragment of a .ffi file (as produced by the interface translator):

(macro ("test.h" 1) "blarg ( x )" "((char)x)")
(macro ("test.h" 2) "rme_test_constant" "blarg(45)")

If you put this in, say, ccl:darwin-x86-headers64;foo;C;foo.ffi, you can process it from lisp like so:

(in-package :ccl)
(require 'parse-ffi)
(parse-standard-ffi-files :foo)

After doing so, evaluate #1$rme_test_constant, and you'll get 45, as you'd expect. (Continue from the cerror whining about making a constant unbound, if needed.). The argument of 1 forces the cdb file on disk to be consulted, rather than just re-using a possibly already-defined defconstant form.

Now, change the .ffi file (in ccl:darwin-x86-headers64;foo;C;foo.ffi, presuming you're on an x86-64 Mac) to read as follows:

(macro ("test.h" 0) "__TYPE" "char")
(macro ("test.h" 1) "blarg ( x )" "((__TYPE)x)")
(macro ("test.h" 2) "rme_test_constant" "blarg(45)")

Do (parse-standard-ffi-files :foo) again. This time, you'll observe that evaluating #1$rme_test_constant will signal an error "foreign variable not found". Perhaps parse-ffi chokes when the type in a cast is a macro?

Uncommenting the lines in eval-c-expression

ccl/library/parse-ffi.lisp

Lines 371 to 372 in f9650bc

;(format t "~& parse failed: ~s ~s" (ffi-macro-name macro) string)
;(format t "~& tokens = ~s, error = ~a" tokens error)
will show that something is getting indigestion.

 parse failed: "rme_test_constant" "blarg(45)"
  tokens = (C::|blarg| C::\( 45 C::\)), error = 45 where ) was expected

This comes up in real life as the following snippet from the MINGW64 winsock2.h header file:

typedef unsigned long u_long;

#define __LONG32 long

#define IOCPARM_MASK 0x7f
#define IOC_VOID 0x20000000
#define IOC_OUT 0x40000000
#define IOC_IN 0x80000000
#define IOC_INOUT (IOC_IN|IOC_OUT)

#define _IOR(x,y,t) (IOC_OUT|(((__LONG32)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))

#define FIONREAD _IOR('f',127,u_long)
(macro ("win64.h" 3) "__LONG32" "long")
(macro ("win64.h" 5) "IOCPARM_MASK" "0x7f")
(macro ("win64.h" 6) "IOC_VOID" "0x20000000")
(macro ("win64.h" 7) "IOC_OUT" "0x40000000")
(macro ("win64.h" 8) "IOC_IN" "0x80000000")
(macro ("win64.h" 9) "IOC_INOUT" "(IOC_IN|IOC_OUT)")
(macro ("win64.h" 11) "_IOR ( x , y , t )" "(IOC_OUT|(((__LONG32)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))")
(macro ("win64.h" 13) "FIONREAD" "_IOR('f',127,u_long)")
(type ("win64.h" 1)
 "u_long"
@xrme xrme added the ffi label Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant