187187 "-D__declspec(x)=" ,
188188 "-D__forceinline=" ,
189189 "-D__inline=" ,
190+ # On Windows, avoid redefining bool to prevent conflicts with MSVC stdbool.h
191+ "-D_Bool=unsigned char" ,
192+ # Don't redefine bool/true/false - let MSVC handle it
190193 ]
191194 if sys .platform .startswith ("win" )
192195 else [
@@ -477,6 +480,7 @@ def load_library(): # noqa: C901
477480
478481# Add the same type definitions to compile args as we use for parsing
479482# This ensures consistency between parsing and compilation
483+ # On Windows, avoid redefining bool to prevent conflicts with MSVC's stdbool.h
480484if not platform .system ().startswith ("win" ):
481485 extra_compile_args .extend (
482486 [
@@ -487,6 +491,15 @@ def load_library(): # noqa: C901
487491 "-D__bool_true_false_are_defined=1" ,
488492 ]
489493 )
494+ else :
495+ # On Windows with MSVC, let the compiler handle bool definitions
496+ # Only define _Bool for consistency in parsing
497+ extra_compile_args .extend (
498+ [
499+ "-D_Bool=unsigned char" ,
500+ # Don't redefine bool/true/false on Windows to avoid conflicts
501+ ]
502+ )
490503
491504libraries = ["smpt" ] # Default library name without lib prefix
492505
@@ -632,11 +645,15 @@ def preprocess_header_manually(header_path):
632645 # Don't redefine __STDC_VERSION__ - that causes the macOS redefinition warning
633646 if platform .system () == "Windows" :
634647 asm_definition = "#define __asm__"
648+ # On Windows, be more careful with bool to avoid MSVC conflicts
649+ bool_definitions = """
650+ #ifndef _Bool
651+ typedef unsigned char _Bool;
652+ #endif
653+ """
635654 else :
636655 asm_definition = "#define __asm__(...)"
637-
638- essential_types = f"""
639- /* Minimal essential types for pycparser - don't redefine __STDC_VERSION__ */
656+ bool_definitions = """
640657#ifndef __bool_true_false_are_defined
641658#define __bool_true_false_are_defined 1
642659typedef unsigned char _Bool;
@@ -649,6 +666,11 @@ def preprocess_header_manually(header_path):
649666#define false 0
650667#endif
651668#endif
669+ """
670+
671+ essential_types = f"""
672+ /* Minimal essential types for pycparser - don't redefine __STDC_VERSION__ */
673+ { bool_definitions }
652674
653675/* Define common GCC attributes away */
654676#define __attribute__(x)
@@ -682,23 +704,31 @@ def try_parse_with_better_args(header_path, header_name):
682704 f"-I{ include_dir } /dyscom-level" ,
683705 ]
684706
685- # Platform-specific __asm__ definition
707+ # Platform-specific __asm__ definition and bool handling
686708 if platform .system () == "Windows" :
687709 asm_definition = "-D__asm__="
710+ # On Windows, be more careful with bool definitions to avoid MSVC conflicts
711+ bool_definitions = [
712+ "-D_Bool=unsigned char" ,
713+ # Don't redefine bool on Windows to avoid MSVC stdbool.h conflicts
714+ ]
688715 else :
689716 asm_definition = "-D__asm__(...)="
717+ bool_definitions = [
718+ "-D_Bool=unsigned char" ,
719+ "-Dbool=unsigned char" ,
720+ "-Dtrue=1" ,
721+ "-Dfalse=0" ,
722+ ]
690723
691724 parsing_attempts = [
692725 # Primary approach: use cpp with optimized args but NO fake libc
693726 {
694727 "use_cpp" : True ,
695728 "cpp_args" : include_paths
729+ + bool_definitions
696730 + [
697731 # Essential definitions without fake libc that causes issues
698- "-D_Bool=unsigned char" , # Use unsigned char instead of char for better compatibility
699- "-Dbool=unsigned char" ,
700- "-Dtrue=1" ,
701- "-Dfalse=0" ,
702732 "-D__attribute__(x)=" ,
703733 "-D__restrict=" ,
704734 "-D__extension__=" ,
@@ -724,11 +754,8 @@ def try_parse_with_better_args(header_path, header_name):
724754 {
725755 "use_cpp" : True ,
726756 "cpp_args" : include_paths
757+ + bool_definitions
727758 + [
728- "-D_Bool=unsigned char" ,
729- "-Dbool=unsigned char" ,
730- "-Dtrue=1" ,
731- "-Dfalse=0" ,
732759 "-D__attribute__(x)=" ,
733760 "-D__declspec(x)=" , # Define away Windows __declspec
734761 "-DSMPT_API=" , # Define away SMPT_API
@@ -809,27 +836,30 @@ def try_parse_with_better_args(header_path, header_name):
809836 print ("Warning: Could not parse any headers. Providing minimal CFFI interface." )
810837 # Add minimal essential types that tests expect with instantiable field definitions
811838 # These provide enough structure for basic testing while being safe to instantiate
839+ # Updated to match actual C structure definitions
812840 collector .typedecls .extend (
813841 [
814- # Basic device structure with essential fields
842+ # Basic device structure with essential fields (matches actual Smpt_device)
815843 """typedef struct {
816844 int file_descriptor;
817845 char device_name[256];
818846 unsigned char packet_number;
819- char _padding[64];
847+ unsigned char is_connection_established;
848+ unsigned char is_version_ack_received;
849+ unsigned char last_packet_number_received;
820850 } Smpt_device;""" ,
821851 # Basic low-level init structure
822852 """typedef struct {
823853 unsigned char packet_number;
824854 unsigned char electrode_count;
825- char _padding[16 ];
855+ unsigned char reserved[14 ];
826856 } Smpt_ll_init;""" ,
827857 # Channel configuration structure
828858 """typedef struct {
829859 unsigned char channel_number;
830860 unsigned char pulse_width;
831861 unsigned char current;
832- char _padding[16 ];
862+ unsigned char reserved[13 ];
833863 } Smpt_ll_channel_config;""" ,
834864 # Version acknowledgment structure
835865 """typedef struct {
@@ -838,14 +868,14 @@ def try_parse_with_better_args(header_path, header_name):
838868 unsigned char version_minor;
839869 unsigned char version_patch;
840870 char version_string[64];
841- char _padding [16];
871+ unsigned char reserved [16];
842872 } Smpt_get_extended_version_ack;""" ,
843- # Generic acknowledgment structure
873+ # Generic acknowledgment structure (matches actual Smpt_ack)
844874 """typedef struct {
845875 unsigned char packet_number;
846876 unsigned char command_number;
847877 unsigned char result;
848- char _padding[16 ];
878+ unsigned char reserved[13 ];
849879 } Smpt_ack;""" ,
850880 ]
851881 )
0 commit comments