Page 1 of 1

C Include Header to PBI Framework

Posted: Fri Oct 09, 2015 8:39 pm
by Starwolf20
Hi everyone.
i needed a PBI include for the new FMOD version. After searching the forum & the Web, it seems that no satisfying tool is available.
I know the not anymore maintened SDK Header Converter but it dont' process enough for the PB V5.x.
Anyway, i have try my luck coding and i end up with something enough advanced for FMOD include & my immediate needs.

Note that some additional work is necessary after the conversion.
The code is rather straightforward but if asked, i could rework the comments part.
Hopes it help someone.

Code: Select all

;======================================================================
; Programm:        C Include to PB Converter
;
; Author:          Starwolf20
; Date:            2015-10-09
; Version:         0.1
; Target Compiler: PureBasic 5.31
; Target OS:       Not tested 
; License:         Free, unrestricted, no warranty whatsoever.
;                  Use at your own risk.
;                  Feel free to modify for your needs.
;======================================================================
; This script is intended to facilitate the conversion from C Include Header to PureBasic Pbi.
; Note that the result still need some work, hopefully 1 ot 2 minutes will do.
;
; The script process Comments, Define, Structure, Enumeration and Prototype declarations.
; Each type of declarations is processed by one pass and stored in array for later use.
; The last step produce a procedure who explain the value of enums.
;======================================================================


EnableExplicit

;==================================================================================================== Parametrage du Traitement.
 Global Header_Fnamed$
 Global DLL_ShortName$
 Global DLL_x32Path$
 Global DLL_x64Path$
 
 Global GTabSet

;==================================================================================================== Enregistrement des resultats.
;--- Tableau des Prototypes.
Global Dim PB_DLL_Init$(1000)
Global PB_DLL_Init_Cpt.l = 0

;--- Tableau des Structures.
Structure Struct_PB_Structure
    Structure_Name$
    Structure_RubriqueName$ 
    Structure_InitialRubriqueName$ 
    Structure_RubriqueType$ 
    Structure_RubriqueComment$ 
EndStructure
Global Dim PB_Structure.Struct_PB_Structure(1000)
Global PB_Structure_Cpt.l = 0

;--- Tableau des Defines.
Structure Struct_PB_Define
    Define_Name$
    Define_Value$ 
    Define_InitialValue$ 
    Define_Comment$ 
EndStructure
Global Dim PB_Define.Struct_PB_Define(1000)
Global PB_Define_Cpt.l = 0

;--- Tableau des Enum.
Structure Struct_PB_Enum
    Enum_Name$
    Enum_ItemName$ 
    ;Enum_InitialValue$ 
    Enum_ItemComment$ 
EndStructure
Global Dim PB_Enum.Struct_PB_Enum(1000)
Global PB_Enum_Cpt.l = 0

;==================================================================================================== Declarations et Macros.
Declare IsStructure(StructureNameToTest$)

Macro M_Open_INOUTFile(LastCall = #False)
 Protected IxFileResult, IxFileSource
 
 If LastCall = #False : IxFileResult = CreateFile(#PB_Any, Right("00" + Str(NEtape), 2) + Header_Fnamed$)
 Else                 : IxFileResult = CreateFile(#PB_Any, Header_Fnamed$ + "_Final.pbi")
 EndIf
 If IxFileResult = 0
    Debug #PB_Compiler_Procedure + ": PB ouverture du fichier Source - " + Header_Fnamed$
    End
 EndIf
 
 If NEtape <= 1 : IxFileSource = ReadFile(#PB_Any,                                    Header_Fnamed$)
 Else :           IxFileSource = ReadFile(#PB_Any, Right("00" + Str(NEtape - 1), 2) + Header_Fnamed$)
 EndIf
 If IxFileSource = 0
    Debug #PB_Compiler_Procedure + ": PB ouverture du fichier Source - " + Header_Fnamed$
    End
 EndIf
 
 EndMacro
Macro M_Close_INOUTFile()
  
 CloseFile(IxFileSource)               ; Ferme le fichier précédemment ouvert
 CloseFile(IxFileResult)   
 
 EndMacro
 
;==================================================================================================== Fonctions diverses.
 Procedure.s Suppr_Comments(HLine$)
 ; Suppression des commentaires entre "/*" et "*/"
 Protected DPos, FPos
 
 Repeat
   Dpos = FindString(Hline$, "/*")
   FPos = FindString(Hline$, "*/")   
   If DPos = 0 Or FPos = 0
      Break
   Else
      HLine$ = Left(Hline$, DPos - 1) + Right(Hline$, Len(Hline$) - FPos - 1)  
   EndIf  
 ForEver     

 ProcedureReturn Hline$
 EndProcedure
 Procedure FindString_Comment(HLine$, FString$, PositionDepart = 1, Mode = #PB_String_CaseSensitive)
 ; Recherche dans la chaine de caracteres en excluant les commentaires entre "/*" et "*/" 
 Protected DPos, FPos
 
 Repeat
   Dpos = FindString(Hline$, "/*")
   FPos = FindString(Hline$, "*/")   
   If DPos = 0 Or FPos = 0
      Break
   Else
      ;Debug "$$" + Left(Hline$, 300)
      HLine$ = Left(Hline$, DPos - 1) + Space(FPos - DPos + 2) + Right(Hline$, Len(Hline$) - FPos - 1)  
      ;Debug "$$" + Left(Hline$, 300)
      ;Debug "tttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
   EndIf  
  ForEver  
  
  ProcedureReturn FindString(HLine$, FString$, PositionDepart, Mode)
  EndProcedure
  
;==================================================================================================== Initialisation.  
Procedure ConvertPass_Initialisation(NEtape, Header_Fnamed$)
 ;--- Preparation du fichier initial par l'ajout d'un Tag (3 caracteres) de ligne.
 Protected HLine$

 M_Open_INOUTFile()
   
 While Eof(IxFileSource) = 0             ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File') 
   HLine$ = ReadString(IxFileSource)     ; Lit le fichier Source ligne par ligne

   If Trim(Hline$) = ""
      WriteStringN(IxFileResult, "COM;") ; on garde la ligne blanche comme commentaire
   Else   
      HLine$ = ReplaceString(HLine$, Chr(9), "   ")       ; Elimination des Tabulations eventuelles
      WriteStringN(IxFileResult, "???" + Hline$)          ; Affiche ligne par ligne le contenu du fichier
   EndIf
 Wend
 
 M_Close_INOUTFile()   
EndProcedure

;==================================================================================================== Commentaires.  
Procedure ConvertPass_Comment(NEtape, Header_Fnamed$) 
;--------------- Etape - Traitement des blocs de commentaires.
Protected Flag_CommentBloc
Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$
 
M_Open_INOUTFile()

Flag_CommentBloc = #False
While Eof(IxFileSource) = 0             ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File') 
 
  HLine$ = ReadString(IxFileSource)     ; Affiche ligne par ligne le contenu du fichier
  Hline_Tag$ = Left(Hline$, 3)
  Hline_Text$ = Right(Hline$, Len(Hline$)-3)
  Hline_Trim$ = Trim(HLine_Text$)
  
  If Hline_Tag$ <> "???"
     WriteStringN(IxFileResult, Hline$)
  Else   
    If Left(Hline_Trim$, 2) = "/*" And Right(Hline_Trim$, 2) = "*/"
       ; detection d'une ligne de commentaires complete.
       WriteStringN(IxFileResult, "COM;" + Hline_Text$)
    Else
      If Left(Hline_Trim$, 2) = "/*"
         WriteStringN(IxFileResult, "COM;" + Hline_Text$)
         Flag_CommentBloc = #True 
      Else
        If Right(Hline_Trim$, 2) = "*/" And Flag_CommentBloc = #True 
           WriteStringN(IxFileResult, "COM;" + Hline_Text$)
           Flag_CommentBloc = #False
        Else    
           ; pas trouve de /* ou de  */ dans la ligne !
           If Flag_CommentBloc = #True
              WriteStringN(IxFileResult, "COM;" + Hline_Text$) 
           Else
              WriteStringN(IxFileResult, Hline$ )  
           EndIf
        EndIf
      EndIf
    EndIf    
  EndIf
 
Wend
 
 M_Close_INOUTFile()      
EndProcedure

;==================================================================================================== Define.
Procedure.s Translate_LitteralValue(Item$)
 Protected PB_Value$
 
 Item$ = Trim(Item$)
 
 If LCase(Right(Item$, 3)) = "ull"
    Item$ = Left(Item$, Len(Item$) - 3 )
 EndIf
 
 
 PB_Value$ = Item$
 If Left(Item$,2)  = "0x"
    PB_Value$ = "$" + Right(Item$, Len(Item$) - 2 )
 EndIf

 
 ProcedureReturn(PB_Value$)
EndProcedure
Procedure ConvertPass_Define(NEtape, Header_Fnamed$) 
 ;--------------- Etape - Traitement des Define.
 ;--- ex
 ;#define FMOD_VERSION    0x00010608  
 ;--> #FMOD_VERSION = $00010608
 ;--- ex
 ;#define FMOD_PRESET_OFF              {  1000,    7,  11, 5000, 100, 100, 100, 250, 0,    20,  96, -80.0f }
 ;--- ex
 ;#define FMOD_CHANNELMASK_FRONT_LEFT             0x00000001
 ;#define FMOD_CHANNELMASK_FRONT_RIGHT            0x00000002
 ;#define FMOD_CHANNELMASK_MONO                   (FMOD_CHANNELMASK_FRONT_LEFT)
 ;#define FMOD_CHANNELMASK_STEREO                 (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT)
 ;--- ex
 ;#define Abs(X) ( ((X) < 0) ? -(X) : (X) )
 
 Protected Flag_CommentBloc
 Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Text2$, Hline_Trim$, HLine_Uncom$
 Protected DPos
 Protected PB_DeclareName$, PB_Declare_InitialValue$, PB_Declare_Comment$, PB_Declare_Value$
 
M_Open_INOUTFile()

While Eof(IxFileSource) = 0             ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File') 
 
  HLine$ = ReadString(IxFileSource)      ; Affiche ligne par ligne le contenu du fichier
  HLine_Tag$ = Left(HLine$,3)
  HLine_Text$ = Right(HLine$,Len(HLine$)-3)
  HLine_Trim$ = Trim(HLine_Text$)
  HLine_UnCom$ = Suppr_Comments(HLine_Text$)
  
  If Hline_Tag$ <> "???"
     WriteStringN(IxFileResult,Hline$  )
  Else   
     If LCase(Left(Hline_Trim$,8)) <> "#define " 
        WriteStringN(IxFileResult,Hline$  )
        Else       
        If FindString(Hline_uncom$,"{") <> 0
           ; non traitée
           WriteStringN(IxFileResult, "IGN" + Hline_Text$)
        Else
           If FindString(Hline_uncom$,"(") <> 0 
             ; non traitée
             WriteStringN(IxFileResult, "IGN" + Hline_Text$)
          Else
              ;#define FMOD_VERSION    0x00010608  
              ;--> #FMOD_VERSION = $00010608
             
             Hline_Text2$ = Trim(ReplaceString(HLine_Text$, "#define ", "", #PB_String_NoCase))
             Dpos = FindString(Hline_Text2$, " ")
             PB_DeclareName$ = Left(Hline_Text2$, DPos - 1 )
             Hline_Text2$ = Trim(Right(Hline_Text2$, Len(Hline_Text2$) - Dpos ))
             
             DPos = FindString(Hline_Text2$, "/*")
             If Dpos = 0 
                PB_Declare_InitialValue$ = Hline_Text2$   
                PB_Declare_Comment$ = ""
             Else
                PB_Declare_InitialValue$ = Trim(Left(Hline_Text2$, DPos - 1 ))
                PB_Declare_Comment$ = Right(Hline_Text2$, Len(Hline_Text2$) - Dpos + 1 )               
                PB_Declare_Comment$ = ReplaceString(PB_Declare_Comment$, "/*", ";")      
                PB_Declare_Comment$ = ReplaceString(PB_Declare_Comment$, "*/", "")                 
             EndIf
             
             If PB_DeclareName$ = "" ;Quick hack for "#define _FMOD_COMMON_H" style
                PB_DeclareName$ = PB_Declare_InitialValue$ 
                PB_Declare_InitialValue$ = Chr(34) + Chr(34) 
             EndIf
                         
             PB_Declare_Value$ = Translate_LitteralValue(PB_Declare_InitialValue$) 
             WriteStringN(IxFileResult, "DF1 #" + PB_DeclareName$ + " = " + PB_Declare_Value$ + " " + PB_Declare_Comment$  )            
             ;Debug "#" + PB_DeclareName$ + " = " + PB_Declare_Value$ + " " + PB_Declare_Comment$ 
             
             ;--- Memorisation des Defines pour reutilisation ulterieure.
             PB_Define_Cpt +1
             PB_Define(PB_Define_Cpt)\Define_Name$                = PB_DeclareName$
             PB_Define(PB_Define_Cpt)\Define_InitialValue$        = PB_Declare_InitialValue$  
             PB_Define(PB_Define_Cpt)\Define_Value$               = PB_Declare_Value$  
             PB_Define(PB_Define_Cpt)\Define_Comment$             = PB_Declare_Comment$
             
          EndIf
        EndIf    
     EndIf
  EndIf
 
Wend
 
M_Close_INOUTFile()        
EndProcedure

;==================================================================================================== Prototypes.
Procedure.s Translate_TypeDeclaration(Item$, Alter$ = "")
 ; Renvoie une declaration de type au format PB. 
 ; ex : int value               --> value.l
 ; ex : void value              --> value
 ; ex : float *value            --> *value
 ; ex : unsigned char* value    --> *value
 ; ex : FMOD_DSP **dsp          --> *dsp
 ; ex : unsigned char Data4[8]  --> Data4.a[8]
 
 ; si Alter$ = "Prototype", on renvoie une declaration de prototype.
 ; ex : FMOD_RESULT FMOD_System_SetOutput      -> Prototype.l __proto_FMOD_System_SetOutput( 
 
 ;---------------------- PB
 ; Nom Extension Encombrement en mémoire Plage 
 ; Byte            .b 1 octet -128 à +127 
 ; Ascii           .a 1 octet 0 à +255 
 ; Caractère       .c 1 octet (en mode ascii) 0 à +255 
 ; Caractère       .c 2 octets (en mode unicode) 0 à +65535 
 ; Word            .w 2 octets -32768 à +32767  
 ; Unicode         .u 2 octets 0 à +65535 
 ; Long            .l 4 octets -2147483648 à +2147483647 
 ; Integer         .i 4 octets (avec compilateur 32-bit) -2147483648 à +2147483647 
 ; Integer         .i 8 octets (avec compilateur 64-bit) -9223372036854775808 à +9223372036854775807 
 ; Float           .f 4 octets illimité (voir informations plus bas)  
 ; Quad            .q 8 octets -9223372036854775808 à +9223372036854775807 
 ; Double          .d 8 octets illimité (voir informations plus bas) 
 ; String          .s longueur de la chaine + 1 illimité 
 ; String Fixe     .s{Longueur} longueur de la chaine illimité 
 
 ;---------------------- C
 ; Type de donnée	Signification	Taille (en octets)	Plage de valeurs acceptée
 ; char	                 Caractère	1	-128 à 127
 ; unsigned char	        Caractère non signé	1	0 à 255
 ; short int	            Entier court	2	-32 768 à 32 767
 ; unsigned short int	   Entier court non signé	2	0 à 65 535
 ; int	                  Entier	2 (sur processeur 16 bits) -32 768 à 32 767
 ;                              4 (sur processeur 32 bits) -2 147 483 648 à 2 147 483 647	                               
 ; unsigned int	         Entier non signé	2 (sur processeur 16 bits) 0 à 65 535
 ;                                        4 (sur processeur 32 bits)	0 à 4 294 967 295                                         
 ; long int	             Entier long	4	-2 147 483 648 à 2 147 483 647
 ; unsigned long int	    Entier long non signé	4	0 à 4 294 967 295
 ; float	                Flottant (réel)	4	3.4*10-38 à 3.4*1038
 ; double	               Flottant double	8	1.7*10-308 à 1.7*10308
  ; long double	          Flottant double long	10	3.4*10-4932 à 3.4*104932

 
 
 Protected LastSpacePos, Item_Type$, Item_Name$, Item_Array$
 Protected Result$, DPosArray
 
 ; Decoupage de la variable Item (a gauche le type et a droite le nom) en fonction du dernier espace
 ; et extraction de l'envetuelle declaration de tableaux.
 LastSpacePos = Len(Item$) - FindString(ReverseString(Item$), " ")
 Item_Type$ = Trim(Left(Item$, LastSpacePos))
 Item_Name$ = Trim(Right(Item$, Len(Item$) -  LastSpacePos - 1))
 DPosArray = FindString(Item_Name$, "[")
 If DPosArray > 0
    Item_Array$ = Trim(Right(Item_Name$, Len(Item_Name$) -  DPosArray + 1))
    Item_Name$ = Trim(Left(Item_Name$, DPosArray - 1))
 Else
    Item_Array$ = ""
 EndIf
 
 ; Detection d'un pointeur par la presence d'une "*".
 If FindString(Item$, "*") <> 0
    If Alter$ = ""
       ProcedureReturn "*" + ReplaceString(Item_Name$, "*", "")
    Else
       ProcedureReturn "TODO : cas non prevu  = prototype pointeur" 
    EndIf
 EndIf
    
 ; Conversion du type.
 Select LCase(Item_Type$)
   Case "char" 
        Result$ = ".b"  
  ;Case "char", "const char" 
  ;     Result$ = ".p-ascii"       
   Case "unsigned char" 
        Result$ = ".a"  
   Case "short int" 
        Result$ = ".w"       
   Case "unsigned short int" 
        Result$ = ".u"      
   Case "float" 
        Result$ = ".f"   
   Case "int", "unsigned int" 
        Result$ = ".i" 
   Case "long int", "unsigned long int" 
        Result$ = ".l"      
   Case "double" 
        Result$ = ".d"    
        
   Default
        If IsStructure(Item_Type$)
           Result$ = "." + Item_Type$                 ;".l"   ou Item_Type$   ????
        Else   
           Result$ = ".l"                             ;".l"   ou Item_Type$   ????
        EndIf
 EndSelect
 
 If Alter$ = ""
    ProcedureReturn Item_Name$ + Result$ + Item_Array$
 Else
    ProcedureReturn "Prototype" + Result$ + " __proto_" + Item_Name$ 
 EndIf   
 
EndProcedure
Procedure.s Translate_Prototype(Item$, IxFileResult)
 ; Si detection d'une declaration de prototype,
 ;    traitement et ecriture vers le fichier output de la syntaxe adaquate et renvoi de "OK"
 ;    de plus, un tableau memorise la liste de prototype pour generer une fonction Initialize()
 ;             lors de la derniere etape de la conversion.  
 ; sinon renvoi de "KO".
 ;
 ; La declaration doit correspondre au modele suivant : 
 ;    type nom_Fonction ( type_parm1 nom_parm1, type_parm1 nom_parm1, type_parm1 nom_parm1 ); 
 ;
 ;ex :
 ;FMOD_RESULT F_API FMOD_System_SetPluginPath             (FMOD_SYSTEM *system, const char *path);
 ;FMOD_RESULT F_API FMOD_System_LoadPlugin                (FMOD_SYSTEM *system, const char *filename, unsigned int *handle, unsigned int priority);
 ;
 ; donne pour resultat : 
 ; ;FMOD_RESULT F_API FMOD_System_SetPluginPath             (FMOD_SYSTEM *system, const char *path);
 ; Prototype.l __proto_FMOD_System_SetPluginPath             (*system, path.p-ascii)
 ; Global FMOD_System_SetPluginPath.__proto_FMOD_System_SetPluginPath
 ;
 ; ;FMOD_RESULT F_API FMOD_System_LoadPlugin                (FMOD_SYSTEM *system, const char *filename, unsigned int *handle, unsigned int priority);
 ; Prototype.l __proto_FMOD_System_LoadPlugin                (*system, filename.p-ascii, *handle, priority.l)
 ; Global FMOD_System_LoadPlugin.__proto_FMOD_System_LoadPlugin
 
 Protected DParanthesePos, FParanthesePos
 Protected LastSpacePos, Proto_Type$, Proto_Name$
 Protected PB_Prototyp$, PB_GlobalDef$
 Protected LArg$, Arg$, VirgPos, Part1$, Part2$
 
 DParanthesePos = FindString( Item$, "(")
 FParanthesePos = FindString( Item$, ");")  
     
 ; doit etre du type "text1 ( text2 );"
 If (DParanthesePos =0) Or (FParanthesePos=0) Or (DParanthesePos > FParanthesePos)
    ProcedureReturn "KO"
 EndIf
 If Left(Item$,1) = "#" ; ne doit pas etre un mot cle commencant par #
    ProcedureReturn "KO"
 EndIf        
     
 Part1$ = Trim(Left(Item$, DParanthesePos - 1))
 Part2$ = Trim(Mid(Item$, DParanthesePos + 1 , FParanthesePos - DParanthesePos -1))
 ;Debug Item$
 ;Debug Part1$
 ;Debug part2$
     
 LastSpacePos = Len(Part1$) - FindString(ReverseString(Part1$), " ")
 Proto_Type$ = Left(Part1$, LastSpacePos - 1)
 Proto_Name$ = Right(Part1$, Len(Part1$) - LastSpacePos - 1)
    
 PB_Prototyp$ = Translate_TypeDeclaration(Part1$, "Prototype") + "("
     
 LArg$ = Part2$
 While LArg$ <> ""
   VirgPos = FindString(LArg$, ",")
   If VirgPos = 0
      Arg$ = LArg$
      LArg$ = ""
   Else
      Arg$ = Left(LArg$, VirgPos - 1)
      LArg$ = Right(LArg$, Len(LArg$) - VirgPos - 1)
   EndIf
      
   PB_Prototyp$ = PB_Prototyp$ + Translate_TypeDeclaration(Arg$) + ", "
 Wend
     
 PB_Prototyp$ = Left(PB_Prototyp$, Len(PB_Prototyp$) - 2) + ")"
 PB_GlobalDef$ = "Global " + Proto_Name$ + ".__proto_" + Proto_Name$ 
 
 ;--- Memorisation des Prototypes pour reutilisation ulterieure.
 PB_DLL_Init_Cpt = PB_DLL_Init_Cpt + 1
 PB_DLL_Init$(PB_DLL_Init_Cpt) = Proto_Name$ + " = GetFunction(DLL_" + DLL_ShortName$ + "," + Chr(34) + Proto_Name$ + Chr(34) + ")"
        
 ;Debug "---"
 ;Debug PB_Prototyp$
 ;Debug PB_DLL_Init$(PB_DLL_Init_Cpt)
 ;Debug "--------------------------------"
     
 WriteStringN(IxFileResult,"PRT;" + Item$  )
 WriteStringN(IxFileResult,"PRT" + PB_Prototyp$  )
 WriteStringN(IxFileResult,"PRT" + PB_GlobalDef$  )
     
 ProcedureReturn "OK"   
EndProcedure  
Procedure ConvertPass_Prototype(NEtape, Header_Fnamed$)
 ;--------------- Etape - Traitement des definitions de prototypes.

 Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
 Protected Result$
 
 M_Open_INOUTFile()

 While Eof(IxFileSource) = 0             ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File') 
   HLine$ = ReadString(IxFileSource)     ; Affiche ligne par ligne le contenu du fichier
   HLine_Tag$ = Left(HLine$, 3)

   If Hline_Tag$ <> "???"
      WriteStringN(IxFileResult, Hline$)
   Else   
      HLine_Text$ = Right(HLine$,Len(HLine$) - 3)
      HLine_Trim$ = Trim(HLine_Text$)
      HLine_UnCom$ = Suppr_Comments(HLine_Text$)
     
      Result$ = Translate_Prototype(HLine_UnCom$, IxFileResult)
      If Result$ = "KO"
         WriteStringN(IxFileResult, Hline$)
      EndIf
   EndIf
 Wend
 
 M_Close_INOUTFile()   
EndProcedure
  
;==================================================================================================== Structures.
Procedure IsStructure(StructureNameToTest$)
 ; renvoie True / False suivant que le nom est present dans le tableau des structures connues
 ; cad si le nom correspond a une structure connue.
 Protected i
 
 i = 1
 While i < PB_Structure_Cpt
  If PB_Structure(i)\Structure_Name$ = StructureNameToTest$
     ProcedureReturn #True
  EndIf
  i +1
 Wend
 
 ProcedureReturn #False
EndProcedure
Procedure.s Translate_Structure(Item$, IxFileSource, IxFileResult)
; Ex :
; typedef int km_per_hour ;
; Ex :
; typedef struct MyStruct newtype;
; Ex :
; typedef struct MyStruct {
;   int data1;
;   char data2;
; } newtype; 
; Ex :
; struct s
; {
;    int   x;
;    float y;
;    char  *z;
; } tee;
; ex : 
; struct FMOD_ASYNCREADINFO
; {
;     void                 *handle;    /* [r] The file handle that was filled out in the open callback. */
;     unsigned int          offset;    /* [r] Seek position, make sure you read from this file offset. */
;     unsigned int          sizebytes; /* [r] how many bytes requested for read. */
;     int                   priority;  /* [r] 0 = low importance.  100 = extremely important (ie 'must read now or stuttering may occur') */
; 
;     void                 *userdata;  /* [r/w] User data pointer specific to this request.  Initially 0, can be ignored or set by the user.  Not related to the file's main userdata member.  */
; 
;     void                 *buffer;    /* [w] Buffer to read file data into. */
;     unsigned int          bytesread; /* [w] Fill this in before setting result code to tell FMOD how many bytes were read. */
; 
;     FMOD_FILE_ASYNCDONE   done;      /* [r] FMOD file system wake up function.  Call this when user file read is finished.  Pass result of file read as a parameter. */
; };
; ---> Syntaxe PB
;  Structure FMOD_ASYNCREADINFO
;   *handle       ; [r] The file handle that was filled out in the open callback.
;   offset.l      ; [r] Seek position, make sure you read from this file offset.
;   sizebytes.l   ; [r] how many bytes requested for read.
;   priority.l    ; [r] 0 = low importance.  100 = extremely important (ie 'must read now or stuttering may occur').
;   *userdata     ; [r/w] User data pointer specific to this request.  Initially 0, can be ignored or set by the user. Not related to the file's main userdata member.
;   *buffer       ; [w] Buffer to read file data into.
;   bytesread.l   ; [w] Fill this in before setting result code to tell FMOD how many bytes were read.
;   *done.__proto_FMOD_ASYNCREADINFO_DONE ; [r] FMOD file system wake up function. Call this when user file read is finished. Pass result of file read as a parameter.
; EndStructure
;
; ex :
; typedef struct
; {
;     unsigned int   Data1;       /* Specifies the first 8 hexadecimal digits of the GUID */
;     unsigned short Data2;       /* Specifies the first group of 4 hexadecimal digits.   */
;     unsigned short Data3;       /* Specifies the second group of 4 hexadecimal digits.  */
;     unsigned char  Data4[8];    /* Array of 8 bytes. The first 2 bytes contain the third group of 4 hexadecimal digits. The remaining 6 bytes contain the final 12 hexadecimal digits. */
; } FMOD_GUID;
; ---> Syntaxe PB 
;  Structure FMOD_GUID
;   Data1.l ; Specifies the first 8 hexadecimal digits of the GUID.
;   Data2.u ; Specifies the first group of 4 hexadecimal digits.
;   Data3.u ; Specifies the second group of 4 hexadecimal digits.
;   Data4.a[8] ; Array of 8 bytes. The first 2 bytes contain the third group of 4 hexadecimal digits. The remaining 6 bytes contain the final 12 hexadecimal digits.
; EndStructure
 
 Protected DPos, FPos, Part1$, Part2$, Part3$
 Protected LastSpacePos, Proto_Type$, Proto_Name$
 Protected PB_Prototyp$, PB_GlobalDef$
 Protected LArg$, Arg$, VirgPos, T$
 Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
 Protected Structure_Name$, Structure_InitialRubriqueName$, Structure_RubriqueName$, Structure_RubriqueComment$
 Protected PB_Structure$
 Protected FPcomment, TabSet
 
 ; doit commencer par "typedef struct " ou par "struct "
 If LCase(Left(Trim(Item$), 7)) <> "typedef" And LCase(Left(Trim(Item$), 6)) <> "struct" 
    ProcedureReturn "KO"
 EndIf
 ;If Left(Item$, 1) = "#" ; ne doit pas etre un mot cle commencant par #
 ;   ProcedureReturn "KO"
 ;EndIf 
 If LCase(Left(Trim(Item$), 12)) = "typedef enum" 
    ProcedureReturn "KO"  
 EndIf
 If LCase(Left(Trim(Item$), 14)) <> "typedef struct" And LCase(Left(Trim(Item$), 6)) <> "struct"  
    WriteStringN(IxFileResult, "STR;" + Item$)
    ProcedureReturn "OK"  
 EndIf
 
 ; Traitement ( on n'en tient pas compte : pas d'equivalent en PB ??? ) des structures du genre :
 ;    typedef struct FMOD_SYSTEM   FMOD_SYSTEM;
 If Right(Suppr_Comments(Item$), 1) = ";"  
    WriteStringN(IxFileResult,"STR;" + Item$) 
    ProcedureReturn "OK"
 EndIf
   
 ;--- Lecture du fichier Source jusqu'a la lecture du "}" final pour avoir la structure entiere dans Item$.
 ;Item_UnCommented$ = Suppr_Comments(Item$)
 While FindString(Item$, "{") = 0 Or FindString(Item$, "}") = 0
   HLine$ = ReadString(IxFileSource) 
   HLine_Tag$ = Left(HLine$, 3)
   HLine_Text$ = Right(HLine$, Len(HLine$) - 3)  
  
   Item$ = Item$ + HLine_Text$
   ;Item_UnCommented$ = Item_UnCommented$ + Uncomment(HLine_Text$)
   
   ;Debug FindString(Item_UnCommented$, "{")
   ;Debug FindString(Item_UnCommented$, "}")
 Wend
 
 ;Debug Item$
 ;Debug Item_UnCommented$
 ;Debug "-----------------------------------"
 
 ;--- Decoupage en 3 parties suivant la position de "{" et de "}"
 DPos = FindString(Item$, "{")
 FPos = FindString(Item$, "}")  
 
 Part1$ = Trim(Left(Item$, DPos - 1))
 Part2$ = Trim(Mid(Item$, DPos + 1 , FPos - DPos -1))
 Part3$ = Trim(Right(Item$, Len(Item$) - FPos - 1))
 
 ;Debug Part1$
 ;Debug Part2$
 ;Debug Part3$
 
 ;--- Traitement de l'entete de declaration Structure PB.
 ; on prend le nom de la structure en fin de declaration (Apres le "}")
 ; ou alors en debut de declaration (avant le "{")
 If Part3$ <> ""
    Structure_Name$ = Left(Part3$, Len(Part3$) - 1) ;On enleve le ";" final.
    WriteStringN(IxFileResult,"STR  Structure " + Structure_Name$) 
 Else
    Structure_Name$ = ReplaceString(Part1$, "typedef" , "", #PB_String_NoCase )   
    Structure_Name$ = ReplaceString(Structure_Name$, "struct" , "", #PB_String_NoCase )      
    Structure_Name$= Trim(Structure_Name$)
    WriteStringN(IxFileResult,"STR  Structure " + Structure_Name$)  
 EndIf
 
 ;--- Boucle de traitement des arguments separés par des ","
 LArg$ = Part2$
 While LArg$ <> ""
   VirgPos = FindString(LArg$, ";")
   If VirgPos = 0
      Arg$ = LArg$
      LArg$ = ""
   Else
      Arg$ = Trim(Left(LArg$, VirgPos - 1))
      LArg$ = Trim(Right(LArg$, Len(LArg$) - VirgPos - 1))
   EndIf
   
   ;Debug Arg$
   ;Debug LArg$
   ;Debug "--"
   
   Structure_InitialRubriqueName$ = Arg$ 
   Structure_RubriqueName$ = Translate_TypeDeclaration(Structure_InitialRubriqueName$) 
   ;Debug  ">>>>>" + Arg$ + ">>>>>" + PB_Structure$
   
   If Left(LArg$,2) = "/*"
      FPcomment = FindString(LArg$, "*/")
      TabSet = GTabSet - Len(Structure_RubriqueName$)
      If TabSet < 1 : TabSet = 1 : EndIf
      Structure_RubriqueComment$ = Left(Larg$, FPcomment + 1) 
      PB_Structure$ = Structure_RubriqueName$ + Space(TabSet) + ";" + Structure_RubriqueComment$   
     
      LArg$ = Right(LArg$, Len(LArg$) - FPcomment - 2)
   Else
      PB_Structure$ = Structure_RubriqueName$
      Structure_RubriqueComment$ = "" 
   EndIf   
  
   ;Debug "Final ---->" + PB_Structure$
   WriteStringN(IxFileResult,"STR    " + PB_Structure$) 
   
   ;--- Memorisation de la structure pour reutilisation ulterieure.
   PB_Structure_Cpt +1
   PB_Structure(PB_Structure_Cpt)\Structure_Name$                = Structure_Name$
   PB_Structure(PB_Structure_Cpt)\Structure_InitialRubriqueName$ = Structure_InitialRubriqueName$  
   PB_Structure(PB_Structure_Cpt)\Structure_RubriqueName$        = Structure_RubriqueName$  
   PB_Structure(PB_Structure_Cpt)\Structure_RubriqueComment$     = Structure_RubriqueComment$
   ;Debug "Structure " + Structure_Name$ + " : " + Structure_RubriqueName$ + " / " +  Structure_InitialRubriqueName$   
   
   
 Wend
     
 WriteStringN(IxFileResult,"STR  EndStructure")
    
 ProcedureReturn "OK"   
EndProcedure  
Procedure ConvertPass_Structure(NEtape, Header_Fnamed$)
 ;--------------- Etape - Traitement des definitions de structures.
 Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
 Protected Result$
 
 M_Open_INOUTFile()

 While Eof(IxFileSource) = 0             ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File') 
   HLine$ = ReadString(IxFileSource)     ; Affiche ligne par ligne le contenu du fichier
   HLine_Tag$ = Left(HLine$, 3)

   If Hline_Tag$ <> "???"
      WriteStringN(IxFileResult, Hline$)
   Else   
      HLine_Text$ = Right(HLine$,Len(HLine$) - 3)
      HLine_Trim$ = Trim(HLine_Text$)
      HLine_UnCom$ = Suppr_Comments(HLine_Text$)
     
      Result$ = Translate_Structure(HLine_UnCom$, IxFileSource, IxFileResult)
      If Result$ = "KO"
         WriteStringN(IxFileResult, Hline$)
      EndIf
   EndIf
 Wend
 
 M_Close_INOUTFile()   
EndProcedure
  
;=================================================================================================== Enumerations.
Procedure.s Translate_Enumeration(Item$, IxFileSource, IxFileResult)  
; // Changing the Default value of enum elements
; enum suit{
;     club=0;
;     diamonds=10;
;     hearts=20;
;     spades=3;
; };
; 
; 
; typedef enum
; {
;    FMOD_OK,                        /* No errors. */
;    FMOD_ERR_BADCOMMAND,            /* Tried To call a function on a Data type that does Not allow this type of functionality (ie calling Sound::lock on a streaming sound). */
;    FMOD_ERR_CHANNEL_ALLOC          /* Error trying To allocate a channel. */
; } FMOD_RESULT;
 
 Protected DPos, FPos, Part1$, Part2$, Part3$
 Protected LastSpacePos, Proto_Type$, Proto_Name$
 Protected PB_Prototyp$, PB_GlobalDef$
 Protected LArg$, Arg$, VirgPos, T$
 Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
 Protected PB_Enumeration$
 Protected FPcomment, TabSet
 Protected Enum_Name$, Enum_ItemName$, Enum_ItemComment$
 
 ; doit commencer par "typedef enum " ou par "enum "
 If LCase(Left(Trim(Item$), 7)) <> "typedef" And LCase(Left(Trim(Item$), 4)) <> "enum" 
    ProcedureReturn "KO"
 EndIf
 ;If Left(Item$, 1) = "#" ; ne doit pas etre un mot cle commencant par #
 ;   ProcedureReturn "KO"
 ;EndIf 
 If LCase(Left(Trim(Item$), 12)) <> "typedef enum" And LCase(Left(Trim(Item$), 4)) <> "enum"  
    WriteStringN(IxFileResult, "STR;" + Item$)
    ProcedureReturn "OK"  
 EndIf
 
 ;; Traitement ( on n'en tient pas compte : pas d'equivalent en PB ??? ) des structures du genre :
 ;;    typedef struct FMOD_SYSTEM   FMOD_SYSTEM;
 ;If Right(Suppr_Comments(Item$), 1) = ";"  
 ;   WriteStringN(IxFileResult,"STR;" + Item$) 
 ;   ProcedureReturn "OK"
 ;EndIf
   
 ;--- Lecture du fichier Source jusqu'a la lecture du "}" final pour avoir l'enum entiere dans Item$.
 ;Item_UnCommented$ = Suppr_Comments(Item$)
 While FindString_Comment(Item$, "{") = 0 Or FindString_Comment(Item$, "}") = 0
   HLine$ = ReadString(IxFileSource) 
   HLine_Tag$ = Left(HLine$, 3)
   HLine_Text$ = Right(HLine$, Len(HLine$) - 3) 
   
   If Trim(HLine_Text$) <> ";"
      Item$ = Item$ + HLine_Text$
   EndIf
   ;Item_UnCommented$ = Item_UnCommented$ + Uncomment(HLine_Text$)
   
   ;Debug FindString(Item_UnCommented$, "{")
   ;Debug FindString(Item_UnCommented$, "}")
 Wend
 
 ;Debug Item$
 ;Debug Item_UnCommented$
 ;Debug "-----------------------------------"
 
 ;--- Decoupage en 3 parties suivant la position de "{" et de "}"
 DPos = FindString_Comment(Item$, "{")
 FPos = FindString_Comment(Item$, "}")  
 
 Part1$ = Trim(Left(Item$, DPos - 1))
 Part2$ = Trim(Mid(Item$, DPos + 1 , FPos - DPos -1))
 Part3$ = Trim(Right(Item$, Len(Item$) - FPos - 1))
 
 ;Debug Part1$
 ;Debug Part2$
 ;Debug Part3$
 
 ;--- Traitement de l'entete de declaration Structure PB.
 ; on prend le nom de la structure en fin de declaration (Apres le "}")
 ; ou alors en debut de declaration (avant le "{")
 If Part3$ <> ""
    Enum_Name$ = Part3$
    WriteStringN(IxFileResult,"STR Enumeration " + Enum_Name$) 
 Else
    T$ = ReplaceString(Part1$, "typedef" , "", #PB_String_NoCase )   
    T$ = ReplaceString(T$, "struct" , "", #PB_String_NoCase )      
    T$= Trim(T$)
    Enum_Name$ = T$
    WriteStringN(IxFileResult,"STR  Enumeration " + Enum_Name$)  
 EndIf
 
  ;--- Boucle de traitement des arguments separés par des ","
 LArg$ = Part2$
 While LArg$ <> ""
   VirgPos = FindString_Comment(LArg$, ",")
   ;CommentPos = FindString(LArg$, "/*")
   ;If VirgPos > CommentPos ; essai d'intercepter une virgule dans le commentaire du dernier item de l'enumeration.
   ;   VirgPos = 0
   ;EndIf
   
   If VirgPos = 0
      Arg$ = LArg$
      LArg$ = ""
      ;--- Cas particulier : le dernier item n'a pas de virgule et est peut être suivi d'un commentaire.
      VirgPos = FindString(Arg$, "/*")
      If VirgPos <> 0
         LArg$ = Arg$
         Arg$ = Trim(Left(LArg$, VirgPos - 1))
         LArg$ = Trim(Right(LArg$, Len(LArg$) - VirgPos + 1))
      EndIf
   Else
      Arg$ = Trim(Left(LArg$, VirgPos - 1))
      LArg$ = Trim(Right(LArg$, Len(LArg$) - VirgPos +1 - 1))
   EndIf
   
   ;Debug Arg$
   ;Debug LArg$
   ;Debug "--"
   
   Enum_ItemName$ = Trim(Arg$) 
   PB_Enumeration$ = "  #" + Enum_ItemName$ 
   ;Debug  ">>>>>" + Arg$ + ">>>>>" + PB_Structure$
   
   Enum_ItemComment$ = ""
   If Left(LArg$,2) = "/*"
      FPcomment = FindString(LArg$, "*/")
      TabSet = GTabSet - Len(PB_Enumeration$)
      If TabSet < 1 : TabSet = 1 : EndIf
      Enum_ItemComment$ = Left(Larg$, FPcomment + 1)
      PB_Enumeration$ = PB_Enumeration$ + Space(TabSet) + ";" + Enum_ItemComment$ 
     
      LArg$ = Right(LArg$, Len(LArg$) - FPcomment - 2)
   EndIf   
  
   ;Debug "Final ---->" + PB_Structure$
   WriteStringN(IxFileResult,"STR " + PB_Enumeration$) 
   
   
   ;--- Memorisation de la structure pour reutilisation ulterieure.
   PB_Enum_Cpt +1
   
   DPos = FindString_Comment(Enum_Name$, ";") ; pour garder le nom uniquement.
   If DPos > 0
      Enum_Name$ = Left(Enum_Name$, Dpos - 1)
   EndIf
   PB_Enum(PB_Enum_Cpt)\Enum_Name$                = Enum_Name$
   
   DPos = FindString_Comment(Enum_ItemName$, "=") ; pour garder le nom uniquement.
   If DPos > 0
      Enum_ItemName$ = Trim(Left(Enum_ItemName$, Dpos - 1))
   EndIf
   PB_Enum(PB_Enum_Cpt)\Enum_ItemName$            = Enum_ItemName$  
   
   PB_Enum(PB_Enum_Cpt)\Enum_ItemComment$         = Enum_ItemComment$
   ;Debug "Enum " + Enum_Name$ + " : " + Enum_ItemName$ + " / " +  Enum_ItemComment$  
    
 Wend
     
 WriteStringN(IxFileResult,"STR EndEnumeration")
    
 ProcedureReturn "OK"   
EndProcedure  
Procedure ConvertPass_Enumeration(NEtape, Header_Fnamed$)         
 ;--------------- Etape - Traitement des definitions de structures.
 Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
 Protected Result$
 
 M_Open_INOUTFile()

 While Eof(IxFileSource) = 0             ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File') 
   HLine$ = ReadString(IxFileSource)     ; Affiche ligne par ligne le contenu du fichier
   HLine_Tag$ = Left(HLine$, 3)

   If Hline_Tag$ <> "???"
      WriteStringN(IxFileResult, Hline$)
   Else   
      HLine_Text$ = Right(HLine$,Len(HLine$) - 3)
      HLine_Trim$ = Trim(HLine_Text$)
      HLine_UnCom$ = Suppr_Comments(HLine_Text$)
     
      Result$ = Translate_Enumeration(HLine_UnCom$, IxFileSource, IxFileResult)
      If Result$ = "KO"
         WriteStringN(IxFileResult, Hline$)
      EndIf
   EndIf
 Wend
 
 M_Close_INOUTFile()   
EndProcedure

;=================================================================================================== Trt Final.
Procedure ConvertPass_Final(NEtape,Header_Fnamed$) 
;--------------- Etape - Traitement des blocs de commentaires.
 Protected Flag_CommentBloc, i
 Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$
 
M_Open_INOUTFile(#True)

Flag_CommentBloc = #False
While Eof(IxFileSource) = 0             ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File') 
 
  HLine$ = ReadString(IxFileSource)      ; Affiche ligne par ligne le contenu du fichier
  Hline_Tag$ = Left(Hline$,3)
  Hline_Text$ = Right(Hline$,Len(Hline$)-3)
  Hline_Trim$ = Trim(HLine_Text$)
  
  If Hline_Tag$ = "???"  Or Hline_Tag$ = "IGN"  
     WriteStringN(IxFileResult, ";IGNORED : " + Hline_Text$ ) 
  Else
     WriteStringN(IxFileResult, Hline_Text$ ) 
  EndIf
Wend

; si detection de prototype, on ajoute une fonction init() a la fin.
If PB_DLL_Init_Cpt > 0
   WriteStringN(IxFileResult, ";" )   
   WriteStringN(IxFileResult, "Procedure " + DLL_ShortName$ + "_Initialize()")
   WriteStringN(IxFileResult, "  Protected DLL_" + DLL_ShortName$)
   WriteStringN(IxFileResult, "  Debug " + Chr(34) +  DLL_ShortName$ + " Initializing." + Chr(34)) 
   WriteStringN(IxFileResult, " ")   
   WriteStringN(IxFileResult, "  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64")
   WriteStringN(IxFileResult, "    DLL_" + DLL_ShortName$ + " = OpenLibrary(#PB_Any, " + Chr(34) + DLL_x64Path$ + Chr(34) + ")")
   WriteStringN(IxFileResult, "  CompilerElse")
   WriteStringN(IxFileResult, "    DLL_" + DLL_ShortName$ + " = OpenLibrary(#PB_Any, " + Chr(34) + DLL_x32Path$ + Chr(34) + ")")
   WriteStringN(IxFileResult, "  CompilerEndIf")
   WriteStringN(IxFileResult, " ")
   WriteStringN(IxFileResult, "  If DLL_" + DLL_ShortName$)
   
   For i = 1 To PB_DLL_Init_Cpt
     WriteStringN(IxFileResult, "     " + PB_DLL_Init$(i))
    Next i
    
   WriteStringN(IxFileResult, "  Endif")
   WriteStringN(IxFileResult, "")
   WriteStringN(IxFileResult, "  ProcedureReturn DLL_" + DLL_ShortName$)
   WriteStringN(IxFileResult, "EndProcedure")
   WriteStringN(IxFileResult, "")
EndIf
 
M_Close_INOUTFile()    
EndProcedure
Procedure Explain_Enum(EnumName$ = "*")

;    Procedure.s FMOD_ErrorString(errcode.l)
;      Protected FMOD_ErrorString.s
;       
;      Select errcode  
;        Case #FMOD_OK:                               FMOD_ErrorString = "No errors."						
;        Case #FMOD_ERR_ALREADYLOCKED:                FMOD_ErrorString = "Tried to call lock a second time before unlock was called."						
;        Case #FMOD_ERR_BADCOMMAND:                   FMOD_ErrorString = "Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound)."						
;        Case #FMOD_ERR_CDDA_DRIVERS:                 FMOD_ErrorString = "Neither NTSCSI nor ASPI could be initialised."						
;        Default:                                     FMOD_ErrorString = "Unknown error."
;      EndSelect    
;      
;      ProcedureReturn FMOD_ErrorString
;    EndProcedure
 

 
 Protected Entete = #False
 Protected CurrentEnum$ = ""
 Protected IxFileResult, ICpt, Comment$
 

 IxFileResult = OpenFile(#PB_Any, Header_Fnamed$ + "_Final.pbi", #PB_File_Append)
 If IxFileResult = 0
    Debug #PB_Compiler_Procedure + ": PB ouverture du fichier Source - " + Header_Fnamed$
    End
 EndIf









ICpt = 1
While ICpt <= PB_Enum_Cpt ; boucle de parcours du tableau d'Enum.
 
  If CurrentEnum$ <> PB_Enum(ICpt)\Enum_Name$
     If Entete = #True
        WriteStringN(IxFileResult, "   Default: Lib$ = " + Chr(34) + "Unknown code." + Chr(34))
        WriteStringN(IxFileResult, " EndSelect")    
        WriteStringN(IxFileResult, "")      
        WriteStringN(IxFileResult, " ProcedureReturn Lib$")
        WriteStringN(IxFileResult, " EndProcedure")
        WriteStringN(IxFileResult, "")  
     EndIf
     Entete = #False
     
     If EnumName$ = "*" Or EnumName$ = PB_Enum(ICpt)\Enum_Name$
        CurrentEnum$ = PB_Enum(ICpt)\Enum_Name$
        WriteStringN(IxFileResult, " Procedure.s Explain_" + CurrentEnum$ + "(Value.l)")
        WriteStringN(IxFileResult, " Protected Lib$")
        WriteStringN(IxFileResult, "")       
        WriteStringN(IxFileResult, " Select Value")
        Entete = #True
     EndIf
  Else
     If EnumName$ = "*" Or EnumName$ = PB_Enum(ICpt)\Enum_Name$ 
        Comment$ = PB_Enum(ICpt)\Enum_ItemComment$
        Comment$ = ReplaceString(Comment$, "/*", "")
        Comment$ = ReplaceString(Comment$, "*/", "")   
        Comment$ = ReplaceString(Comment$, Chr(34), "'")     
        Comment$ = Trim(Comment$) 
        WriteStringN(IxFileResult, "   Case #" + PB_Enum(ICpt)\Enum_ItemName$ + ": Lib$ = " + Chr(34) + Comment$ + Chr(34))
				EndIf
     
     
  EndIf
  
 
 ICpt +1
Wend
     If Entete = #True
        WriteStringN(IxFileResult, "   Default: Lib$ = " + Chr(34) + "Unknown code." + Chr(34))
        WriteStringN(IxFileResult, " EndSelect")    
        WriteStringN(IxFileResult, "")      
        WriteStringN(IxFileResult, " ProcedureReturn Lib$")
        WriteStringN(IxFileResult, " EndProcedure")
        WriteStringN(IxFileResult, "")  
     EndIf




 CloseFile(IxFileResult)               ; Ferme le fichier précédemment ouvert

 
EndProcedure




;==================================================================================================== Parametrage du Traitement.
Global Header_Fnamed$ = "Fmod_Complet.h"
Global DLL_ShortName$ = "FMOD"
Global DLL_x32Path$ = "FmodL.dll"
Global DLL_x64Path$ = "Fmod64.dll"

Global GTabSet = 35

;==================================================================================================== Traitement.
ConvertPass_Initialisation(    1, Header_Fnamed$)  
ConvertPass_Comment(           2, Header_Fnamed$)  
ConvertPass_Define(            3, Header_Fnamed$)  
ConvertPass_Structure(         4, Header_Fnamed$) 
ConvertPass_Prototype(         5, Header_Fnamed$) 
ConvertPass_Enumeration(       6, Header_Fnamed$) 
ConvertPass_Final(             7, Header_Fnamed$) 

Explain_Enum("FMOD_RESULT")