but for the moment, managing optional procedure parameters is a bit tricky.
to remedy this problem I've made a little code
it also adds a “Quick help” giving the procedure syntax
a comment line above the procedure can be added for a quick description of the procedure
Code: Select all
EnableExplicit
Procedure.s lirefic(nom.s,nobom=1)
  Protected txt.s,n,sf
  n=ReadFile(-1,nom)
  sf=ReadStringFormat(n)
  txt=ReadString(n,#PB_File_IgnoreEOL)
  ;If sf<>#PB_Ascii:txt=Mid(txt,2):EndIf
  CloseFile(n)   
  ProcedureReturn txt
EndProcedure
Procedure ecrirefic(nom.s,txt.s,format=#PB_UTF8)
  Protected n
  If FileSize(nom)>=0:DeleteFile(nom):EndIf
  n=OpenFile(-1,nom,format):WriteString(n,txt,format):CloseFile(n)   
EndProcedure
#separateurs=" =:;,()[]{}+-/*.\<>?%|&"+#CR$+#LF$+Chr(34)
Declare.s Stringparse(t.s,before.s,after.s,pi=0)
Procedure.s Stringparse(t.s,before.s,after.s,pi=0)
    Protected pf
    pi=FindString(t,before,pi+1)
    If pi=0:ProcedureReturn:EndIf 
    pf=FindString(t,after,pi):If pf=0:pf=Len(t):EndIf
    pi+Len(before)
    ProcedureReturn Mid(t,pi,pf-pi)
EndProcedure
Procedure FindStringRev(t.s,find.s,p=0,mode=#PB_String_CaseSensitive)
    Protected l=Len(find)
    If p=0:p=Len(t):EndIf
    Repeat
        If p=0 Or Mid(t,p,L)=find:Break:EndIf
        p-1
    ForEver
    ProcedureReturn p
EndProcedure
Procedure.i FindStringww(txt.s,mot.s,p=1,mode=0); findstring whole word
    Repeat
        p=FindString(txt,mot,p,mode):If p=0:Break:EndIf
        If FindString(#separateurs,Mid(txt,p-1,1))>0 And FindString(#separateurs,Mid(txt,p+Len(mot),1))>0:ProcedureReturn p:EndIf
        p+Len(mot)
    ForEver
EndProcedure
Procedure.s ReplaceStringww(txt.s,mot.s,rep.s,p=1,mode=0); ReplaceString whole word
  Protected lm,lr
  
  lm=Len(mot)
  lr=Len(rep)
  Repeat
    p=FindStringww(txt,mot,p+1,mode):If p=0:Break:EndIf
    txt=Left(txt,p-1)+rep+Mid(txt,p+lm)
    p+lm-lr+1
  ForEver
  ProcedureReturn txt
EndProcedure
;####################################################################################################################################################
#g=Chr(34)
Procedure.s codefiltre(txt.s);----- crée une version du code contenant des ";"  à la place des commentaires et des """ dans les strings pour faciliter l'analyse du code
    Protected i,n,ch,co,  c.w
    
    n=Len(txt)
    Dim t.w(n-1)
    CopyMemory(@ txt,@ t(0),n*2)
    For i=0 To n-1
        c=t(i)
        Select c
            Case 34:ch=~ch
            Case 59:co=1
            Case 13:co=0
        EndSelect      
        If ch:c=34 :EndIf
        If co:c=59:EndIf
        t(i)=c
    Next
    CopyMemory(@ t(0),@ txt,n*2)
    ProcedureReturn txt
EndProcedure
Procedure.s listeparam(List p.s(),txt.s,pi=1);----- met les parametres de proc dans une liste et retourne un string contenant les parametres 
    Protected i,n,np,ch,pd,pdc,pfc,finc
    Protected.s c,fct
    ClearList(p())
    
    For i=pi To Len(txt)
        c=Mid(txt,i,1)
        If ch=0
            If c="(":np+1:If np=1:pd=i:pdc=i:EndIf:EndIf
            If c=")":np-1:If np=0:finc=1:EndIf:EndIf
            If c="," And np=1:finc=1:EndIf
            If finc:
              AddElement(p()):p()=Trim(Mid(txt,pdc+1,i-pdc-1)):pdc=i
              If finc And np=0:Break:EndIf
              finc=0
            EndIf
        EndIf
        If c=#g:ch=~ch:EndIf
      Next
      ;ForEach p():Debug p():Next:Debug "---"+Mid(txt,pd+1,i-pd-1):End
      ProcedureReturn Mid(txt,pd+1,i-pd-1)
EndProcedure
Procedure.s paramx(List p.s(), n, nval,declaration) ; <- retourne les parametres sous forme litérales
    Protected i, r.s,v.s
    ForEach p()
        i+1:If i>n:Break:EndIf
        v=StringField(p(),Bool(i>nval)+1,"=")
        If declaration=0 And FindString(v,"("):v=Stringparse(v," ","(")+"()":EndIf
        r+","+v
      Next
    ProcedureReturn Mid(r,2)
EndProcedure
Procedure.s parametres_optionels(fic.s) ;-------- gestion des parametres optionnels du fichier fic (il y a tjrs la possibilité de les gérer nous même (si on met les versions numerotées)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows :#lgsep=#CRLF$
    CompilerCase #PB_OS_Linux   :#lgsep=#LF$
    CompilerCase #PB_OS_MacOS   :#lgsep=#CR$
  CompilerEndSelect
  
  Protected i,n,ni,p,pp,pi,pl,pf,ppi,ppf,num,npo,npf,ok,decl
  Protected.s dossier, fasm,flib,param,paramo, nom,nomnum,  proccode,proccodei,remplace,nums,ret,deb,QuickHelp
  NewList l.s() ; liste parametre
  NewList ll.s() ; liste parametre
  
  pf=1
  Repeat
    
    ;========================================== recup de la Proceduredll
    pi=FindString(fic,"ProcedureDLL",pf):If pi=0:Break:EndIf
    pf=FindString(fic,"EndProcedure",pi)+12:If pf=12:Break:EndIf
    proccode=Mid(fic,pi,pf-pi)
    proccodei=proccode
    
    pl=FindString(proccode,#lgsep)
    nom=Trim(Stringparse(proccode," ","("))
    ok=1:For i=1 To Len(nom):If FindString(#separateurs,Mid(nom,i,1)):ok=0:EndIf:Next:If ok=0 Or nom="":Continue:EndIf
    num=Val(Right(nom,1))
    param=listeparam(l(),proccode)
    
    ;========================================== QuickHelp 
    QuickHelp=" QuickHelp "+nom+"("+param+") - "
    p=FindStringRev(fic,#lgsep,pi-3)+Len(#lgsep)
    If Mid(fic,p,1)=";":p=p+1:Else:p=pi:QuickHelp=";"+QuickHelp+#lgsep:EndIf
    fic =Left(fic ,p-1)+QuickHelp+Mid(fic ,p)
    pi+Len(QuickHelp)
    pf+Len(QuickHelp)
   
    If num:Continue:EndIf; on abandonne si n° à la 1er occurence
       
    ;========================================== suppression de ses valeurs par defaut
    paramo=param
    While FindString(paramo,"="):paramo=ReplaceString(paramo,"="+Stringparse(paramo+",","=",","),""):Wend
    proccode=ReplaceString(proccode,param,paramo)
    
    npo=CountString(param,"="); !!!
    If npo=0:Continue:EndIf; on abandonne si nombre de param optionel=0
    
    ;========================================== creation des versions numérotées 
    npf=ListSize(l())-npo
    
    deb=Left(proccode,FindString(proccode,"(")-1)
    nomnum=nom+Str(npo+1)
    remplace=ReplaceString(proccode,nom,nomnum,0 ,1,1)
    If FindString(proccode,"ProcedureReturn")>0:ret="ProcedureReturn ":Else:ret="":EndIf
    For i=npo To 1 Step -1
      If i>1:nums=Str(i):Else:nums="":EndIf
      remplace+#lgsep+deb+nums+"("+paramx(l(),npf+i-1,100,1)+")"+#lgsep+ret+nomnum+"("+paramx(l(),npf+npo,npf+i-1,0)+")"+#lgsep+"EndProcedure"
    Next
        
    fic =Left(fic ,pi-1)+remplace+Mid(fic ,pf)
    pf+Len(remplace)-Len(proccodei)
    
    ;========================================== remplacement des appels de la Proceduredll (et DeclareDLL) par leur version numérotée
    p=0
    Repeat
      p=FindStringww(fic,nom,p+1,#PB_String_NoCase):If p=0:Break:EndIf
      pp=FindStringRev(fic,#lgsep,p)+Len(#lgsep)
      If Mid(fic,pp,12)="ProcedureDLL" Or Mid(fic,pp,1)=";" Or Mid(fic,p+Len(nom),1)<>"(":Continue:EndIf  ; !!!     
      
      paramo=listeparam(ll(),fic,p)
      If Bool(Mid(fic,pp,10)="DeclareDLL")
        param=paramx(l(),npf+npo,100,1)
      Else
        paramx(l(),npf+npo,npf,0)
        param=paramo       
        For i=ListSize(ll()) To ListSize(l()) -1
          SelectElement(l(),i)
          param+","+Mid(l(),FindString(l(),"=")+1)
        Next
      EndIf
      
      nums=Str(npo+1)
      fic=ReplaceString(fic,nom,nom+nums,#PB_String_NoCase,p,1)
      fic=ReplaceString(fic,paramo,param,#PB_String_NoCase,p,1)
      If p<pf:pf+Len(nums)+Len(param)-Len(paramo):EndIf
    ForEver
    
  ForEver
  
  ProcedureReturn fic
EndProcedure
Define.s code,fic,chd,chs,   s,libname,pg.i
chs=ProgramParameter(0)
fic=GetFilePart(chs)
libname=Left(fic,FindString(fic,".")-1)
code=parametres_optionels(lirefic(chs))
chd=GetTemporaryDirectory()+"tmp.pb"
ecrirefic(chd,code)
pg=RunProgram(#PB_Compiler_Home+"Compilers\pbcompilerc",chd+" /OPTIMIZER /PURELIBRARY /OUTPUT "+libname,"", #PB_Program_Open|#PB_Program_Read)
While ProgramRunning(pg):If AvailableProgramOutput(pg):s+ReadProgramString(pg) + #CRLF$:EndIf:Wend:CloseProgram(pg)
If s>""
  MessageRequester("Error :",s)
Else
  MessageRequester("Create Lib","Your lib has been created as "+#g+libname+#g+#CRLF$+"Resart your compiler to use it")
EndIf
create an executable
go to
tool -> configure tool
-> new
commandline : select the executable path
Arguments : %FILE
Name : Create Lib
all you have to do is Tools -> Create lib to create / update your lib
PS: this code is a bit messy, if you encounter a problem, please let me know and I'll fix it.


