@@ -1255,6 +1255,10 @@ for code in 'sbBcdCEFgfhHiIlLqQPzuUZXvO':
12551255
12561256 // always contains NULLs:
12571257 struct fielddesc fmt_nil ;
1258+
1259+ // Result of _ctypes_get_simple_type_chars. Initialized just after
1260+ // the rest of formattable, so we stash it here.
1261+ char simple_type_chars [26 ];
12581262};
12591263
12601264static struct formattable formattable ;
@@ -1315,8 +1319,8 @@ _Py_COMP_DIAG_PUSH
13151319
13161320/* Delayed initialization. Windows cannot statically reference dynamically
13171321 loaded addresses from DLLs. */
1318- void
1319- _ctypes_init_fielddesc (void )
1322+ static void
1323+ _ctypes_init_fielddesc_locked (void )
13201324{
13211325 /* Fixed-width integers */
13221326
@@ -1432,9 +1436,11 @@ for base_code, base_c_type in [
14321436
14331437 TABLE_ENTRY_SW (d , & ffi_type_double );
14341438#if defined(Py_HAVE_C_COMPLEX ) && defined(Py_FFI_SUPPORT_C_COMPLEX )
1435- TABLE_ENTRY (C , & ffi_type_complex_double );
1436- TABLE_ENTRY (E , & ffi_type_complex_float );
1437- TABLE_ENTRY (F , & ffi_type_complex_longdouble );
1439+ if (Py_FFI_COMPLEX_AVAILABLE ) {
1440+ TABLE_ENTRY (C , & ffi_type_complex_double );
1441+ TABLE_ENTRY (E , & ffi_type_complex_float );
1442+ TABLE_ENTRY (F , & ffi_type_complex_longdouble );
1443+ }
14381444#endif
14391445 TABLE_ENTRY (g , & ffi_type_longdouble );
14401446 TABLE_ENTRY_SW (f , & ffi_type_float );
@@ -1466,21 +1472,75 @@ for base_code, base_c_type in [
14661472 formattable .fmt_bool .code = '?' ;
14671473 formattable .fmt_bool .setfunc = bool_set ;
14681474 formattable .fmt_bool .getfunc = bool_get ;
1475+
1476+ /*[python input]
1477+ all_chars = "cbBhHiIlLdCEFfuzZqQPXOv?g"
1478+ print(f' assert(sizeof(formattable.simple_type_chars) == {len(all_chars)+1});')
1479+ print(f' int i = 0;')
1480+ for char in all_chars:
1481+ ident_char = {'?': 'bool'}.get(char, char)
1482+ print(f" if (formattable.fmt_{ident_char}.code) "
1483+ + f"formattable.simple_type_chars[i++] = '{char}';")
1484+ print(f" formattable.simple_type_chars[i] = 0;")
1485+ [python start generated code]*/
1486+ assert (sizeof (formattable .simple_type_chars ) == 26 );
1487+ int i = 0 ;
1488+ if (formattable .fmt_c .code ) formattable .simple_type_chars [i ++ ] = 'c' ;
1489+ if (formattable .fmt_b .code ) formattable .simple_type_chars [i ++ ] = 'b' ;
1490+ if (formattable .fmt_B .code ) formattable .simple_type_chars [i ++ ] = 'B' ;
1491+ if (formattable .fmt_h .code ) formattable .simple_type_chars [i ++ ] = 'h' ;
1492+ if (formattable .fmt_H .code ) formattable .simple_type_chars [i ++ ] = 'H' ;
1493+ if (formattable .fmt_i .code ) formattable .simple_type_chars [i ++ ] = 'i' ;
1494+ if (formattable .fmt_I .code ) formattable .simple_type_chars [i ++ ] = 'I' ;
1495+ if (formattable .fmt_l .code ) formattable .simple_type_chars [i ++ ] = 'l' ;
1496+ if (formattable .fmt_L .code ) formattable .simple_type_chars [i ++ ] = 'L' ;
1497+ if (formattable .fmt_d .code ) formattable .simple_type_chars [i ++ ] = 'd' ;
1498+ if (formattable .fmt_C .code ) formattable .simple_type_chars [i ++ ] = 'C' ;
1499+ if (formattable .fmt_E .code ) formattable .simple_type_chars [i ++ ] = 'E' ;
1500+ if (formattable .fmt_F .code ) formattable .simple_type_chars [i ++ ] = 'F' ;
1501+ if (formattable .fmt_f .code ) formattable .simple_type_chars [i ++ ] = 'f' ;
1502+ if (formattable .fmt_u .code ) formattable .simple_type_chars [i ++ ] = 'u' ;
1503+ if (formattable .fmt_z .code ) formattable .simple_type_chars [i ++ ] = 'z' ;
1504+ if (formattable .fmt_Z .code ) formattable .simple_type_chars [i ++ ] = 'Z' ;
1505+ if (formattable .fmt_q .code ) formattable .simple_type_chars [i ++ ] = 'q' ;
1506+ if (formattable .fmt_Q .code ) formattable .simple_type_chars [i ++ ] = 'Q' ;
1507+ if (formattable .fmt_P .code ) formattable .simple_type_chars [i ++ ] = 'P' ;
1508+ if (formattable .fmt_X .code ) formattable .simple_type_chars [i ++ ] = 'X' ;
1509+ if (formattable .fmt_O .code ) formattable .simple_type_chars [i ++ ] = 'O' ;
1510+ if (formattable .fmt_v .code ) formattable .simple_type_chars [i ++ ] = 'v' ;
1511+ if (formattable .fmt_bool .code ) formattable .simple_type_chars [i ++ ] = '?' ;
1512+ if (formattable .fmt_g .code ) formattable .simple_type_chars [i ++ ] = 'g' ;
1513+ formattable .simple_type_chars [i ] = 0 ;
1514+ /*[python end generated code: output=e6e5098a02f4b606 input=72031a625eac00c1]*/
1515+
14691516}
14701517#undef FIXINT_FIELDDESC_FOR
14711518_Py_COMP_DIAG_POP
14721519
1473- struct fielddesc *
1474- _ctypes_get_fielddesc ( const char * fmt )
1520+ static void
1521+ _ctypes_init_fielddesc ( void )
14751522{
14761523 static bool initialized = false;
14771524 static PyMutex mutex = {0 };
14781525 PyMutex_Lock (& mutex );
14791526 if (!initialized ) {
1480- _ctypes_init_fielddesc ();
1527+ _ctypes_init_fielddesc_locked ();
14811528 initialized = true;
14821529 }
14831530 PyMutex_Unlock (& mutex );
1531+ }
1532+
1533+ char *
1534+ _ctypes_get_simple_type_chars (void ) {
1535+ _ctypes_init_fielddesc ();
1536+ return formattable .simple_type_chars ;
1537+ }
1538+
1539+ struct fielddesc *
1540+ _ctypes_get_fielddesc (const char * fmt )
1541+ {
1542+ _ctypes_init_fielddesc ();
1543+
14841544 struct fielddesc * result = NULL ;
14851545 switch (fmt [0 ]) {
14861546/*[python input]
0 commit comments