File format of the user libs ?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Zebuddi123
Enthusiast
Enthusiast
Posts: 796
Joined: Wed Feb 01, 2012 3:30 pm
Location: Nottinghamshire UK
Contact:

File format of the user libs ?

Post by Zebuddi123 »

Hi to all


could someone please advice me as to the fileformat of the userlibs also does the pbcompiler read in the procedures from the userlibs etc (i presume so as with restarting the compiler after installing new libs) have looked through japbe source nothing there only ref to purelibraries are in checkcompilerflags() and [GetTailBiteFile1() GetTailBiteFile2() but these dont seem to be called anywhere only defined)

how would i go about reading in from the userlibs the procedure names etc (where can i find info on the header offsets etc and how to read it like the compiler does)

i have hacked some code that does the job but not for all files (and it is a hack as i have had to look through the user libs for identifiers for which parts to pull (it pulls the proc name and params for my libs all droopys but the minizip i loose the paramaters and am only left with the procname )

its driving me mad :shock:

Any help much appreciated

Thanks in advance

Zebuddi :D
malleo, caput, bang. Ego, comprehendunt in tempore
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: File format of the user libs ?

Post by ts-soft »

the Compilerway: (works only in ascii)

Code: Select all

EnableExplicit

Procedure.s GetFunctionNames(List Functions.s())
  Protected.s Text, result, tmp
  Protected.i Compiler = RunProgram(#PB_Compiler_Home + "Compilers\pbcompiler", "/STANDBY", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Write | #PB_Program_Hide)
  Protected PureBasicVersion.s
  
  If Compiler
    If IsProgram(Compiler)
      Repeat
        tmp = ReadProgramString(compiler)
        If Left(tmp, 8) = "STARTING"
          PureBasicVersion = Trim(Right(tmp, Len(tmp) - 13))
        EndIf
      Until tmp = "READY"
      WriteProgramStringN(Compiler, "FUNCTIONLIST")
      
      Repeat
        Text = ReadProgramString(Compiler)
        If Text <> "OUTPUT" + #TAB$ + "COMPLETE"
          AddElement(Functions())
          Functions() = Trim(StringField(Text, 1, "("))
        EndIf
      Until Text = "OUTPUT" + #TAB$ + "COMPLETE"
      WriteProgramStringN(Compiler, "END")
      CloseProgram(Compiler)
    EndIf

    FirstElement(Functions()) 
    DeleteElement(Functions())
    ForEach Functions()
      result + Functions() + " "
    Next
  EndIf
  
  ProcedureReturn Trim(result)
EndProcedure

NewList Functions.s()

GetFunctionNames(Functions())

ForEach Functions()
  Debug Functions()
Next
The native way:

Code: Select all

EnableExplicit

Procedure GetAllLibFunc(Libname.s, Map FuncInfo.s())
  Protected size.i
  Protected file.i
  Protected buff.i
  Protected offset.i  
  Protected ende.i
  Protected i.l
  
  Protected LibFunc.s
  Protected LibDesc.s
  Protected LibParam.l
  Protected LibCount.l
  
  file = ReadFile(#PB_Any, Libname)
  
  If (file)
    size = Lof(file)
    buff = AllocateMemory(size)
    If (Not buff)
      ProcedureReturn 0
    EndIf    
    ReadData(file, buff, size)
    CloseFile(file)
  Else
    ProcedureReturn 0
  EndIf
  
  If (Not PeekS(buff + 8, 4, #PB_Ascii) = "3BIL")
    ProcedureReturn 0
  EndIf
  
  ende = PeekL(buff + 4) + 12

  offset = 20
  offset + Len(PeekS(buff + offset, -1, #PB_Ascii)) + 2

  LibCount = PeekB(buff + offset)
  
  If (LibCount)
    offset + 1
    
    For i = 0 To LibCount-1
      offset + Len(PeekS(buff + offset, -1, #PB_Ascii)) + 1
    Next
    
    offset + 1
  Else
    offset + 2
  EndIf

  offset + Len(PeekS(buff + offset, -1, #PB_Ascii)) + 1

  LibCount = PeekB(buff + offset)
  
  If (LibCount)
    offset + 1
    
    For i = 0 To LibCount-1
      offset + Len(PeekS(buff + offset, -1, #PB_Ascii) ) + 1
    Next
    
  Else
    offset + 1
  EndIf
    
  If (ende > offset)
    
    Repeat      
      
      LibFunc = PeekS(buff + offset, -1, #PB_Ascii)            
      offset + Len(LibFunc) + 1
      LibParam = PeekB(buff + offset)
      offset + 1
      
      If (LibParam)
        For i = 0 To LibParam-1
          offset + 1
        Next        
      EndIf
      
      offset + 4
      LibDesc = PeekS(buff + offset, -1, #PB_Ascii)
      offset + Len(LibDesc) + 1

      FuncInfo(LCase(LibFunc)) = LibDesc
      
    Until (ende <= offset)
    
  EndIf
 
EndProcedure

NewMap FuncInfo.s()
GetAllLibFunc(#PB_Compiler_Home + "PureLibraries\Gadget", FuncInfo())

ForEach FuncInfo()
  Debug MapKey(FuncInfo()) + FuncInfo()
Next

Greetings - Thomas
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
Zebuddi123
Enthusiast
Enthusiast
Posts: 796
Joined: Wed Feb 01, 2012 3:30 pm
Location: Nottinghamshire UK
Contact:

Re: File format of the user libs ?

Post by Zebuddi123 »

@Thomas

Thank you very much. That`s spot on, it would be nice to see the code the compiler actually uses.

Is there a way for the compiler version to actually pull the libname also ?

again thank you very much.

Zebuddi. :D
malleo, caput, bang. Ego, comprehendunt in tempore
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: File format of the user libs ?

Post by ts-soft »

Read the documentation:

Code: Select all

RunProgram(#PB_Compiler_Home + "SDK\CompilerInterface.txt")
Greetings - Thomas
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: File format of the user libs ?

Post by skywalk »

Hi ts-soft,
Is there a similar way to read the Constants and Values and Structures and Fields from the various Residents files?
I would like to programmatically link constants to specific commands and verify my own constants don't 'step on' existing values. The Structure Viewer is too painful to use. Slow and does not export all. Only 1 at a time :(
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: File format of the user libs ?

Post by ts-soft »

I can only help you on Structure and Members:

Code: Select all

EnableExplicit

Structure strucMember
  Name.s
  List Members.s()
EndStructure

Structure strucName
  List Name.strucMember()
EndStructure


Procedure GetStructures(*p.strucName)
  Protected.i Compiler = RunProgram(#PB_Compiler_Home + "Compilers\pbcompiler", "/STANDBY", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Write | #PB_Program_Hide)
  Protected.s tmp, Text
  
  If Compiler
    If IsProgram(Compiler)
      Repeat
        tmp = ReadProgramString(compiler)
      Until tmp = "READY"
      WriteProgramStringN(Compiler, "STRUCTURELIST")
      Repeat
        Text = ReadProgramString(Compiler)
        If Text <> "OUTPUT" + #TAB$ + "COMPLETE"
          AddElement(*p\Name())
          *p\Name()\Name = Text
        EndIf
      Until Text = "OUTPUT" + #TAB$ + "COMPLETE"
      FirstElement(*p\Name())
      DeleteElement(*p\Name())
      ForEach *p\Name()
        WriteProgramStringN(Compiler, "STRUCTURE" + #TAB$ + *p\Name()\Name)
        Repeat
          Text = ReadProgramString(Compiler)
          If Text <> "OUTPUT" + #TAB$ + "COMPLETE"
            AddElement(*p\Name()\Members())
            *p\Name()\Members() = Text
          EndIf
        Until Text = "OUTPUT" + #TAB$ + "COMPLETE"        
      Next
      WriteProgramStringN(Compiler, "END")
      CloseProgram(Compiler)
    EndIf
  EndIf 
EndProcedure

Define.strucName structs
GetStructures(@structs)
With structs
  ForEach \Name()
    Debug "Structure " + \Name()\Name
    ForEach \Name()\Members()
      Debug "   " + \Name()\Members()
    Next
    Debug "EndStructure"
    Debug ""
  Next
EndWith
have fun :wink:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: File format of the user libs ?

Post by skywalk »

Thanks ts-soft! That is very cool 8)
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: File format of the user libs ?

Post by Danilo »

ts-soft wrote:I can only help you on Structure and Members:
Get informations about Structures, Interfaces, and Procedures:

GetPBInfo.pb:

Code: Select all

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 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 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 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"

    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())+"Procedures.pb")
        ForEach procedures()
            WriteStringN(0,procedures())
        Next
        CloseFile(0)
    EndIf

    
    StopCompiler(pb)
    Debug "Finish."
EndIf
Writes the files 'Structures.pb', 'Interfaces.pb', and 'Procedures.pb' at the end. Change it to what you need.
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Re: File format of the user libs ?

Post by yrreti »

Hi Danilo and ts-soft
I may be a little late from when this was posted, as I just noticed this topic when I was
searching for something. But I wanted to thank you for sharing your code on how to get
this information. Works nice.
Post Reply