Repository: ctypesgen/ctypesgen

Issue:
interface is generated with short == int
I had a very old project that used an old version of CTypesGen. with 32 bit python 2  and wanted to bring the build tools up to date.  Installed latest cygwin64 with gcc , the current CtypesGen, and made the changes to go to 64 bit python 3 including some minor changes to support typing.  Tests failed and traced it to size of structures and that to size of uint16.

This line in the interface is __uint16_t = c_int# /usr/include/machine/_default_types.h: 57
and should be __uint16_t = c_ushort# /usr/include/machine/_default_types.h: 57

This is caused by misinterpreting the phrase SHORT INT  as INT  but would have been fine with just SHORT.

not sure this is the right place to fix this but made a change to get_ctypes_type in ctypesparser.pv  so it does not "forget" short when it next sees int in the typ.specifiers list



Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 94e9abe..0750831 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@ major work was made towards code modernization and quality.
 - Added support for sized integer types on Windows
 - Added support to handle `restrict` and `_Noreturn` keywords
 - Added name formats to posix library loader
+- Fixed mapping of 'short int' to c_short
 
 ### v1.0.2
 
diff --git a/ctypesgen/ctypedescs.py b/ctypesgen/ctypedescs.py
index ce8b023..e787804 100755
--- a/ctypesgen/ctypedescs.py
+++ b/ctypesgen/ctypedescs.py
@@ -61,6 +61,8 @@ ctypes_type_map = {
 }
 
 ctypes_type_map_python_builtin = {
+    ("int", True, -1): "c_short",
+    ("int", False, -1): "c_ushort",
     ("int", True, 2): "c_longlong",
     ("int", False, 2): "c_ulonglong",
     ("size_t", True, 0): "c_size_t",
diff --git a/ctypesgen/parser/ctypesparser.py b/ctypesgen/parser/ctypesparser.py
index 5d8dd30..f92ee08 100644
--- a/ctypesgen/parser/ctypesparser.py
+++ b/ctypesgen/parser/ctypesparser.py
@@ -130,6 +130,8 @@ class CtypesParser(CParser):
                 signed = False
             elif specifier == "long":
                 longs += 1
+            elif specifier == "short":
+                longs = -1
             else:
                 typename = str(specifier)
 


Test patch:
diff --git a/tests/testsuite.py b/tests/testsuite.py
index defc1ef..426d29a 100755
--- a/tests/testsuite.py
+++ b/tests/testsuite.py
@@ -234,6 +234,55 @@ struct foo
         self.assertEqual(struct_foo._fields_, [("is_bar", ctypes.c_bool), ("a", ctypes.c_int)])
 
 
+class IntTypesTest(unittest.TestCase):
+    "Test correct parsing and generation of different integer types"
+
+    @classmethod
+    def setUpClass(cls):
+        header_str = """
+struct int_types {
+    short t_short;
+    short int t_short_int;
+    unsigned short t_ushort;
+    unsigned short int t_ushort_int;
+    int t_int;
+    long t_long;
+    long int t_long_int;
+    long long t_long_long;
+    long long int t_long_long_int;
+    unsigned long long int t_u_long_long_int;
+    long int unsigned long t_long_int_u_long;
+};
+"""
+        cls.module, _ = generate(header_str)
+
+    @classmethod
+    def tearDownClass(cls):
+        del cls.module
+        cleanup()
+
+    def test_int_types(self):
+        """Test if different integer types are correctly parsed"""
+        module = IntTypesTest.module
+        struct_int_types = module.struct_int_types
+        self.assertEqual(
+            struct_int_types._fields_,
+            [
+                ("t_short", ctypes.c_short),
+                ("t_short_int", ctypes.c_short),
+                ("t_ushort", ctypes.c_ushort),
+                ("t_ushort_int", ctypes.c_ushort),
+                ("t_int", ctypes.c_int),
+                ("t_long", ctypes.c_long),
+                ("t_long_int", ctypes.c_long),
+                ("t_long_long", ctypes.c_longlong),
+                ("t_long_long_int", ctypes.c_longlong),
+                ("t_u_long_long_int", ctypes.c_ulonglong),
+                ("t_long_int_u_long", ctypes.c_ulonglong),
+            ],
+        )
+
+
 class SimpleMacrosTest(unittest.TestCase):
     """Based on simple_macros.py"""