GetPBInfo - get constants structures procedures interfaces

Share your advanced PureBasic knowledge/code with the community.
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

GetPBInfo - get constants structures procedures interfaces

Post by Danilo »

Just updated GetPBInfo.pb for PureBasic 5.10 and added the new CONSTANTLIST feature.

GetPBInfo.pb gets information about structures, interfaces, constants and PB functions directly from the PB compiler
and saves the information to files "Structures.pb", "Interfaces.pb", "Constants.pb", and "Procedures.pb".

For API functions known by PureBasic, look at "PureBasic\Compilers\APIFunctionListing.txt".

Can be useful for IDE and tool writers to get this information.

Code: Select all

;
; GetPBInfo.pb
;
; by Danilo
;
; Version: PureBasic 5.10
;
; [X] Create temporary executable in the source directory
; [ ] Create unicode executable
;
CompilerIf #PB_Compiler_Unicode
    CompilerError "Please turn off compiler option 'Create unicode executable'"
CompilerEndIf


EnableExplicit

#Compiler = #PB_Compiler_Home+"compilers\pbcompiler.exe"

Procedure StartCompiler()
    ProcedureReturn RunProgram(#Compiler,"/STANDBY","",#PB_Program_Open|#PB_Program_Read|#PB_Program_Write|#PB_Program_Hide)
EndProcedure

Procedure StopCompiler(compiler)
    WriteProgramStringN(compiler, "END")
    WaitProgram(compiler,5000)
    CloseProgram(compiler)
EndProcedure

Procedure SendCompilerCommand(compiler,command$)
    If ProgramRunning(compiler)
        WriteProgramStringN(compiler, command$)
    EndIf
EndProcedure

Procedure.s GetCompilerOutput(compiler)
    If AvailableProgramOutput(compiler)
        ProcedureReturn ReadProgramString(compiler)
    EndIf
EndProcedure

Procedure FillList(compiler,List out.s(),space=0)
    Protected out$
    Protected space$=Space(space)
    While out$<>"OUTPUT"+#TAB$+"COMPLETE" And Left(out$,5)<>"ERROR"
        out$=GetCompilerOutput(compiler)
        If out$ And out$<>"OUTPUT"+#TAB$+"COMPLETE" And Left(out$,5)<>"ERROR" And FindString("0123456789",Mid(out$,1,1))=0
            AddElement(out())
            out()=space$+out$
        EndIf
    Wend
EndProcedure

Procedure FillConstantList(compiler,List out.s(),space=0)
    Protected out$
    Protected space$=Space(space)
    While out$<>"OUTPUT"+#TAB$+"COMPLETE" And Left(out$,5)<>"ERROR"
        out$=GetCompilerOutput(compiler)
        If out$<>"" And out$<>"OUTPUT"+#TAB$+"COMPLETE" And Left(out$,5)<>"ERROR" And FindString("0123456789",Mid(out$,2,1))=0
            If FindString("01",Mid(out$,1,1))
                out$ = "#"+Mid(out$,2,Len(out$)-1)
                out$ = ReplaceString(out$,#TAB$," = ")
                out$ = ReplaceString(out$,"# = ","#")
            ElseIf FindString("2",Mid(out$,1,1))
                Protected i, found_non_printable = #False
                Protected oldout$ = out$
                Protected sconst_value$  = StringField(oldout$,3,Chr(9))
                out$ = "#"+StringField(oldout$,2,#TAB$)
                For i = 1 To Len(sconst_value$)
                    If Asc(Mid(sconst_value$,i)) < 32 Or Asc(Mid(sconst_value$,i)) > 126
                        found_non_printable = #True
                    EndIf
                Next i
                If out$ = "#TAB$"
                    out$ + " = Chr(9)"
                ElseIf out$ = "#HT$"
                    out$ + " = Chr(9)"
                ElseIf out$ = "#CRLF$"
                    out$ + " = Chr(13) + Chr(10)"
                ElseIf out$ = "#LFCR$"
                    out$ + " = Chr(10) + Chr(13)"
                ElseIf out$ = "#LF$"
                    out$ + " = Chr(10)"
                ElseIf out$ = "#CR$"
                    out$ + " = Chr(13)"
                ElseIf out$ = "#DOUBLEQUOTE$"
                    out$ + " = Chr(34)"
                ElseIf out$ = "#DQUOTE$"
                    out$ + " = Chr(34)"
                ElseIf found_non_printable = #False
                    out$ + " = " + #DQUOTE$ + StringField(oldout$,3,#TAB$) + #DQUOTE$
                Else
                    out$ + " ="
                    Protected temp$ = StringField(oldout$,3,#TAB$)
                    For i = 0 To Len(sconst_value$)-1
                        out$ + " Chr("+Str(PeekB(@temp$+(i*SizeOf(Character)))) + ") +"
                    Next
                EndIf
                out$ = RTrim(out$,"+")
                out$ = Trim(out$)
            Else
                Debug out$
            EndIf
            out$ = Trim(out$)
            If out$
                AddElement(out())
                out()=space$+out$
            EndIf
        EndIf
    Wend
EndProcedure

Procedure GetStructureList(compiler,List out.s())
    If ProgramRunning(compiler)
        SendCompilerCommand(compiler,"STRUCTURELIST")
        FillList(compiler,out())
    EndIf
EndProcedure

Procedure GetProcedureList(compiler,List out.s())
    If ProgramRunning(compiler)
        SendCompilerCommand(compiler,"FUNCTIONLIST")
        FillList(compiler,out())
    EndIf
EndProcedure

Procedure GetConstantsList(compiler,List out.s())
    If ProgramRunning(compiler)
        SendCompilerCommand(compiler,"CONSTANTLIST")
        FillConstantList(compiler,out())
    EndIf
EndProcedure


Procedure GetInterfaceList(compiler,List out.s())
    If ProgramRunning(compiler)
        SendCompilerCommand(compiler,"INTERFACELIST")
        FillList(compiler,out())
    EndIf
EndProcedure

Procedure GetStructureInfo(compiler,struct$,List out.s())
    If ProgramRunning(compiler)
        SendCompilerCommand(compiler,"STRUCTURE"+#TAB$+struct$)
        FillList(compiler,out(),4)
    EndIf
EndProcedure

Procedure GetInterfaceInfo(compiler,interf$,List out.s())
    If ProgramRunning(compiler)
        SendCompilerCommand(compiler,"INTERFACE"+#TAB$+interf$)
        FillList(compiler,out(),4)
    EndIf
EndProcedure


Procedure WaitCompilerReady(compiler)
    Protected out$
    While out$<>"READY" And Left(out$,5)<>"ERROR"
        out$ = GetCompilerOutput(compiler)
        If out$
            Debug out$
        EndIf
    Wend
EndProcedure

Define  pb, out$
NewList constants.s()
NewList structures.s()
NewList procedures.s()
NewList interfaces.s()

NewList structureInfo.s()
NewList interfaceInfo.s()

pb = StartCompiler()
If pb
    WaitCompilerReady(pb)

    GetStructureList(pb,structures())
    Debug "found "+Str(ListSize(structures()))+" structures"

    GetProcedureList(pb,procedures())
    Debug "found "+Str(ListSize(procedures()))+" procedures"

    GetConstantsList(pb,constants())
    Debug "found "+Str(ListSize(constants()))+" constants"
    SortList(constants(),#PB_Sort_Ascending|#PB_Sort_NoCase)

    GetInterfaceList(pb,interfaces())
    Debug "found "+Str(ListSize(interfaces()))+" interfaces"

    ClearList(structureInfo())
    ForEach structures()
        AddElement(structureInfo())
        structureInfo()="Structure "+structures()
        GetStructureInfo(pb,structures(),structureInfo())
        AddElement(structureInfo())
        structureInfo()="EndStructure"
        AddElement(structureInfo())
        structureInfo()=""
    Next

    ClearList(interfaceInfo())
    ForEach interfaces()
        AddElement(interfaceInfo())
        interfaceInfo()="Interface "+interfaces()
        GetInterfaceInfo(pb,interfaces(),interfaceInfo())
        AddElement(interfaceInfo())
        interfaceInfo()="EndInterface"
        AddElement(interfaceInfo())
        interfaceInfo()=""
    Next

    If CreateFile(0,GetPathPart(ProgramFilename())+"Structures.pb")
        ForEach structureInfo()
            WriteStringN(0,structureInfo())
        Next
        CloseFile(0)
    EndIf

    If CreateFile(0,GetPathPart(ProgramFilename())+"Interfaces.pb")
        ForEach interfaceInfo()
            WriteStringN(0,interfaceInfo())
        Next
        CloseFile(0)
    EndIf

    If CreateFile(0,GetPathPart(ProgramFilename())+"Constants.pb")
        ForEach constants()
            WriteStringN(0,constants())
        Next
        CloseFile(0)
    EndIf

    If CreateFile(0,GetPathPart(ProgramFilename())+"Procedures.pb")
        ForEach procedures()
            WriteStringN(0,procedures())
        Next
        CloseFile(0)
    EndIf

    
    StopCompiler(pb)
    Debug "DONE."
EndIf
Last edited by Danilo on Sat Sep 19, 2015 11:49 pm, edited 1 time in total.
sec
Enthusiast
Enthusiast
Posts: 789
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: GetPBInfo.pb for PB 5.10

Post by sec »

Does Anything secret find in "Structures.pb", "Interfaces.pb", "Constants.pb", and "Procedures.pb"? :evil:
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: GetPBInfo.pb for PB 5.10

Post by Danilo »

sec wrote:Does Anything secret find in "Structures.pb", "Interfaces.pb", "Constants.pb", and "Procedures.pb"? :evil:
No, what secrets did you expect? :lol:

The info is not useful for most PB users, as it is the same as structure viewer etc. within the PB IDE.
It can be useful for guys wanting to replace the PB IDE, in this case you could use the info for Intellisense popup and such stuff.
I used it successfully to extract PB structures when I wrote a structure compare-tool some time ago, so I could compare PB with C WinAPI structures for checking correctness.
A guy in german forum was asking for a full list of all PB commands yesterday. It is just some cases where it can be useful, but there are no secrets in it AFAIK. :)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: GetPBInfo.pb for PB 5.10

Post by netmaestro »

Firstly, let me say thank you very much for this, it will be very useful to me. However, it runs a couple of seconds and outputs that it found 665 structures, 1489 procedures, 13897 constants and 2111 interfaces, and then I get a box saying 'pbcompiler.exe has stopped working', 'Check online for a solution to the problem' and 'Close the program'. I have all compiler options unselected and 'Create temporary executable in the source directory' is checked.

PB 5.10 final with event and window quickfix libs, Win 7. When it started crashing I moved my userlibs out and restarted the IDE, no change.
BERESHEIT
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: GetPBInfo.pb for PB 5.10

Post by skywalk »

Outstanding Danilo!
Way faster than the Structure Viewer since it is stored in a text file for quick browsing.

Code: Select all

STARTING	5.10	PureBasic 5.10 (Windows 7 - x86)
READY
found 664 structures
found 1485 procedures
found 13798 constants
found 2111 interfaces
DONE.
Last edited by skywalk on Thu Feb 28, 2013 1:07 am, edited 1 time in total.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Re: GetPBInfo.pb for PB 5.10

Post by yrreti »

Thanks for this too, but the program always crashes for me, giving the windows 7 error pbcompiler.exe has stopped working,
when running the following code?
I'm using PB 5.10 final with Win 7 64bit.

Code: Select all

     ClearList(structureInfo())
     ForEach structures()
         AddElement(structureInfo())
         structureInfo()="Structure "+structures()
         GetStructureInfo(pb,structures(),structureInfo())
         AddElement(structureInfo())
         structureInfo()="EndStructure"
         AddElement(structureInfo())
         structureInfo()=""
         Delay(5)
     Next
If I comment that part out, it runs fine.
I don't have time to troubleshoot right now, but any ideas on what to check?
Thanks for the interesting program

yrreti
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: GetPBInfo.pb for PB 5.10

Post by rsts »

Runs perfectly on win 8 x64 pb5.1 32 bit.

Thanks for posting :)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: GetPBInfo.pb for PB 5.10

Post by netmaestro »

Uninstalled PB thru control panel, deleted my PureBasic folder, reinstalled PB 5.10 in a new clean folder. Works fine now. Thanks again!
BERESHEIT
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Re: GetPBInfo.pb for PB 5.10

Post by yrreti »

Continuation from previous post, but now using PB5.11 beta 1.
After a little investigation, I found that the Procedure GetStructureInfo crash problem occurs
when struct$="BITMAP".
I tried testing just using the following:
BITMAPCOREHEADER
BITMAPCOREINFO
BITMAPFILEHEADER
BITMAPINFO
BITMAPINFOHEADER
BITMAPV4HEADER
BITMAPV5HEADER
But they all failed.
Only by bypassing by using "BITMAP" as follows, will the program run fine.

Code: Select all

Procedure GetStructureInfo(compiler,struct$,List out.s())
  If ProgramRunning(compiler)
    Debug "STRUCTURE:  "+struct$
    If FindString(struct$,"BITMAP",1)=0
      SendCompilerCommand(compiler,"STRUCTURE"+#TAB$+struct$)
      Delay(50)
      FillList(compiler,out(),4)
    EndIf
  EndIf
EndProcedure
Because I'm definitely not familiar yet with those commands, could this mean that the BITMAP structure section
is defective? All the other structs work fine.

yrreti
LuCiFeR[SD]
666
666
Posts: 1033
Joined: Mon Sep 01, 2003 2:33 pm

Re: GetPBInfo.pb for PB 5.10

Post by LuCiFeR[SD] »

Danilo, nice! very nice. Thanks :)
Denis
Enthusiast
Enthusiast
Posts: 704
Joined: Fri Apr 25, 2003 5:10 pm
Location: Doubs - France

Re: GetPBInfo.pb for PB 5.10

Post by Denis »

Nice tool Danilo :D

works without problem under Seven pro x64
A+
Denis
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Re: GetPBInfo.pb for PB 5.10

Post by Nico »

Window 7 x64 compiler crash with Purebasic 5.1 x86
User avatar
Bisonte
Addict
Addict
Posts: 1226
Joined: Tue Oct 09, 2007 2:15 am

Re: GetPBInfo.pb for PB 5.10

Post by Bisonte »

Win7 (x64) - PB 5.10 compiled with x86 and x64 works without error....
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: GetPBInfo.pb for PB 5.10

Post by Danilo »

yrreti wrote:Because I'm definitely not familiar yet with those commands, could this mean that the BITMAP structure section
is defective? All the other structs work fine.

yrreti
Could you try please with a clean PB install, like netmaestro did? Maybe something goes wrong when
there are 3rd party Resident files installed, or something like this.
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Re: GetPBInfo.pb for PB 5.10

Post by yrreti »

Danilo, I'm sorry, I just couldn't get back to you. I've been quite busy lately.
I did finally get to try it on a clean install, and it worked fine. At this point
I'm going to add my addins one at a time, until the problem occurs again.
Then I can decide what to do about it, because that addin may be causing other
issues too. Again, thanks for sharing this nice program.

yrret
Post Reply