trolldbois / ctypeslib

Generate python ctypes classes from C headers. Requires LLVM clang
http://trolldbois.blogspot.com/search?q=ctypeslib
MIT License
216 stars 58 forks source link

unnamed unions in struct causes syntax error #139

Open jmgurney opened 6 days ago

jmgurney commented 6 days ago

Tested with: 2.3.5.dev2+g0df7325

Gives the following input (from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/netinet6/in6.h:153)

typedef unsigned char __uint8_t;
typedef unsigned short __uint16_t;
typedef unsigned int __uint32_t;

typedef struct in6_addr {
        union {
                __uint8_t   __u6_addr8[16];
                __uint16_t  __u6_addr16[8];
                __uint32_t  __u6_addr32[4];
        } __u6_addr;                    /* 128-bit IP6 address */
} in6_addr_t;

When run through clang2py, produces a python script that fails to import:

$ python
Python 3.10.14 (main, May 18 2024, 01:48:55) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import minunion
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jmg/github/ngtcp2/minunion.py", line 127
    class union_union (unnamed at minunion.h:6:9)(Union):
                       ^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?

This is because the unnamed union is given an incompatible name by clang: union_union (unnamed at minunion.h:6:9).

If I'm pointed to a location where munging the name should be done, I'll generate a PR w/ a test and the name munging so things don't break.

jmgurney commented 6 days ago

so, looks like adding the following just before the name = '%s_%s' line in get_unique_name in codegen/handler.py:

            if 'unnamed at' in name:
                name = re.sub('[^a-zA-Z0-9]', '_', name)

is a solution by replacing bad chars w/ underscores. This should be safe as both line and character position is included.