Seite 1 von 2

Tool: CreatePreprocess

Verfasst: 22.09.2015 14:06
von GPI
Wer viel mit Macros arbeitet wird schon einmal auf das Problem gestoßen sein, das bei einen Fehler nur die Zeile mit den Macroaufruf markiert wird, aber man ansonsten keinen richtigen Hinweis bekommt, wo der Fehler nun eigentlich steckt.

Das Tool ist dazu gedacht, den compiler mit "/PREPROCESS" und "/COMMEND" aufzurufen, um eine große Datei zu bekommen, bei der alle Makros expandiert, compilerif aufgelöst wurden und alle Dateien eingefügt wurden. Zusätzlich entfernt das Tool noch alle überflüssigen Kommentare (jede Zeile wäre sonst quasi doppelt vorhanden) und entfernt die nicht mehr nötigen Macro-Definitionen.

Als Parameter einfach "%file" (inklusive ") eingeben.

Code: Alles auswählen

;"%FILE"
Procedure FindCommend(*pos.character)
  Protected *start=*pos
  Protected isDQuote
  Protected isQuote
  While *pos\c>0
    If isDQuote
      If *pos\c='"'
        isDQuote=#False
      EndIf
    ElseIf isQuote
      If *pos\c=39 ;'
        isQuote=#False
      EndIf
    Else
      Select *pos\c
        Case '"'
          isDQuote=#True
        Case 39;'
          isQuote=#True
        Case ';'
          Break
      EndSelect
    EndIf
    *pos+SizeOf(character)
  Wend
  ProcedureReturn (*pos-*start )/SizeOf(character)
EndProcedure


file$=ProgramParameter()
pb$=GetEnvironmentVariable("PB_TOOL_Compiler")
If file$ And FileSize(file$)>0
  dir$ = GetPathPart(file$)
  outfile$=file$+".pre.pb"
  DeleteFile(dir$+outfile$)
  OpenConsole()  
  ;Compiler = RunProgram(pb$, Chr(34)+file$+Chr(34)+" /COMMENTED /PREPROCESS "+Chr(34)+outfile$+Chr(34), dir$,#PB_Program_Wait)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows
      Compiler = RunProgram(pb$, Chr(34) + file$ + Chr(34) + " /COMMENTED /PREPROCESS " + Chr(34) + outfile$ + Chr(34), dir$, #PB_Program_Open)
    CompilerDefault
      Compiler = RunProgram(pb$, Chr(34) + file$ + Chr(34) + " -c -pp " + Chr(34) + outfile$ + Chr(34), dir$, #PB_Program_Open)
  CompilerEndSelect
  If compiler 
    WaitProgram(compiler)
    ExitCode=ProgramExitCode(compiler)
    PrintN("Errorcode:"+Str(ExitCode))
    
    CloseProgram(compiler)
  EndIf
  
  If compiler And ExitCode=0
    NewList file.s()
    
    Define in,str.s,lastcom.s
    Macro output(a)
      AddElement(file())
      file()=a
    EndMacro
    PrintN("")
    Print("Remove unnecassary comments...")
    
    Define empty
    
    in=ReadFile(#PB_Any,outfile$)
    If in
      While Not Eof(in)
        line+1
        str=ReadString(in)
        If Left(str,1)=";"
          If lastcom<>""
            If Trim(Left(lastcom,FindCommend(@lastcom)))=""
              output("  "+lastcom)
            Else
              output("; "+lastcom)
            EndIf
          EndIf      
          lastcom=Right(str,Len(str)-2)
        Else
          If Left(Trim(str),6)="Macro "
            isMacro=#True
            str=""
          ElseIf Left(Trim(str),8)="EndMacro"
            isMacro=#False
            str=""
          ElseIf isMacro
            str=""
          EndIf      
          If lastcom<>""
            If empty
              output(";;")
            EndIf
            empty=#False
            x=FindCommend(@lastcom)
            If str<>Left(lastcom,x)
              
              output( "; "+lastcom)
              If str<>""
                output( str)
              EndIf
              
            Else
              output(lastcom)
            EndIf
            lastcom=""
          ElseIf str<>""
            output(str)
            empty=#True
          EndIf
          
        EndIf
        
        
      Wend
      
      CloseFile(in)
    EndIf
    PrintN("done")
    PrintN("Removed lines:"+Str(line-ListSize(file())))
    Print("Write File ...")
    out=CreateFile(#PB_Any,outfile$)
    If out
      ForEach file()
        WriteStringN(out,file())
      Next
      CloseFile(out)
    EndIf
    PrintN("done")
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      PrintN("")  
      PrintN("Press [Return]")
      
      Input()      
    CompilerEndIf
    
    RunProgram(GetEnvironmentVariable("PB_TOOL_IDE"), #DQUOTE$ + outfile$ + #DQUOTE$, "")  
  Else
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      PrintN("")  
      PrintN("Press [Return]")
      
      Input()      
    CompilerEndIf
  EndIf
EndIf

Re: Tool: CreatePreprocess

Verfasst: 22.09.2015 14:53
von ts-soft
:allright: Sehr nützlich!

Re: Tool: CreatePreprocess

Verfasst: 22.09.2015 15:00
von RSBasic
Coole Sache, danke. :allright:

Re: Tool: CreatePreprocess

Verfasst: 22.09.2015 16:15
von ts-soft
Leider funktioniert das ganze noch nicht unter Linux, hierzu ist folgende Zeile zu ändern:

Code: Alles auswählen

  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows
      Compiler = RunProgram(pb$, Chr(34) + file$ + Chr(34) + " /COMMENTED /PREPROCESS " + Chr(34) + outfile$ + Chr(34), dir$, #PB_Program_Wait)
    CompilerDefault
      Compiler = RunProgram(pb$, Chr(34) + file$ + Chr(34) + " -c -pp " + Chr(34) + outfile$ + Chr(34), dir$, #PB_Program_Wait)
  CompilerEndSelect
Consolenausgabe fehlt auch noch, hab ich aber im moment noch nicht hinbekommen. Ich hoffe mal, das es so auch unter MacOS funktioniert, kann es aber nicht testen.

Gruß
Thomas

Re: Tool: CreatePreprocess

Verfasst: 22.09.2015 16:40
von GPI
Danke, ich habs mal eingefügt.

Unter Windows wird die ausgabe automatisch in die Console gestopft. Von daher hab ich da nichts eingefügt. Ist aber auch eigentlich nicht so wichtig, die Anzeige ist nur interessant, wenn ein direkter Fehler in Quellcode vorhanden ist (fehlende Klammern etc.). Ich würde dann das "input()" auch rausnehmen.

Re: Tool: CreatePreprocess

Verfasst: 23.09.2015 00:55
von ts-soft
Ich hab es mal ohne Console gemacht. Sollte Crossplattform sein.

Code: Alles auswählen

EnableExplicit

Procedure FindCommend(*pos.character)
  Protected *start = *pos
  Protected isDQuote
  Protected isQuote
  While *pos\c > 0
    If isDQuote
      If *pos\c = '"'
        isDQuote = #False
      EndIf
    ElseIf isQuote
      If *pos\c = 39 ;'
        isQuote = #False
      EndIf
    Else
      Select *pos\c
        Case '"'
          isDQuote = #True
        Case 39;'
          isQuote = #True
        Case ';'
          Break
      EndSelect
    EndIf
    *pos + SizeOf(character)
  Wend
  ProcedureReturn (*pos-*start ) / SizeOf(character)
EndProcedure


Define.s file$, outfile$, compiler$, parameter$
Define.i line, isMacro, x, out

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    parameter$ = " /COMMENTED /PREPROCESS "
  CompilerDefault
    parameter$ = " --commented --preprocess "
CompilerEndSelect

compiler$ = GetEnvironmentVariable("PB_TOOL_Compiler")
file$ = ProgramParameter()
outfile$ = file$ + ".pre.pb"

If RunProgram(compiler$, #DQUOTE$ + file$ + #DQUOTE$ + parameter$ + #DQUOTE$ + outfile$ + #DQUOTE$, GetPathPart(file$), #PB_Program_Wait)
  NewList file.s()
  Define in, str.s, lastcom.s
  
  Macro output(a)
    AddElement(file())
    file() = a
  EndMacro
  
  in = ReadFile(#PB_Any, outfile$)
  If in
    While Not Eof(in)
      line + 1
      str = ReadString(in)
      If Left(str,1) = ";"
        If lastcom <> ""
          If Trim(Left(lastcom, FindCommend(@lastcom))) = ""
            output("  " + lastcom)
          Else
            output("; " + lastcom)
          EndIf
        EndIf     
        lastcom = Right(str, Len(str) - 2)
      Else
        If Left(Trim(str), 6) = "Macro "
          isMacro = #True
          str = ""
        ElseIf Left(Trim(str), 8) = "EndMacro"
          isMacro = #False
          str = ""
        ElseIf isMacro
          str = ""
        EndIf     
        If lastcom <> ""
          x = FindCommend(@lastcom)
          If str <> Left(lastcom, x)
            output( "; " + lastcom)
            If str <> ""
              output(str)
            EndIf
          Else
            output(lastcom)
          EndIf
          lastcom = ""
        ElseIf str <> ""
          output(str)
        EndIf
      EndIf
    Wend
    CloseFile(in)  
  EndIf
  out = CreateFile(#PB_Any, outfile$)
  If out
    ForEach file()
      WriteStringN(out,file())
    Next
    CloseFile(out)
  EndIf
  RunProgram(GetEnvironmentVariable("PB_TOOL_IDE"), #DQUOTE$ + outfile$ + #DQUOTE$, "")  
EndIf
Da PB-Source nicht immer mit der IDE geöffnet wird, unter anderem OS, habe ich das auch gleich geändert.

Re: Tool: CreatePreprocess

Verfasst: 28.10.2015 10:14
von NicTheQuick
Danke nochmal für das Tool. Sehr praktisch. Konnte ich gestern und heute sehr gut gebrauchen. :allright:

Trotzdem noch ein irritierendes Fehlerchen:
Das Tool zeigt den expandierten Code auch dann an, wenn ein Fehler im Code ist, man ihn aber schon mal vorher erfolgreich expandiert hatte.
Das heißt, wenn es einen Compiler-Fehler gab, wird dieser nicht angezeigt, sondern einfach das Resultat vom letzten Mal geöffnet. Das hab ich aber zum Glück schnell gemerkt.

Außerdem funktioniert es scheinbar nicht mit ungespeicherten Codes. Oder ich mache was falsch.

Re: Tool: CreatePreprocess

Verfasst: 14.11.2015 22:53
von GPI
Stimmt. wenn es ein Compilerfehler gab, wird kein neuer output erzeugt, ist jetzt drin.

Und ja, der Code muss erst gespeichert werden.

Re: Tool: CreatePreprocess

Verfasst: 15.11.2015 01:00
von Sicro
GPI hat geschrieben:Wer viel mit Macros arbeitet wird schon einmal auf das Problem gestoßen sein, das bei einen Fehler nur die Zeile mit den Macroaufruf markiert wird, aber man ansonsten keinen richtigen Hinweis bekommt, wo der Fehler nun eigentlich steckt.
Bei einem Fehler in einem Macro wird doch noch zusätzlich ein Fenster geöffnet ("Macro-Fehler"), in dem die fehlerhafte Zeile im Macro-Code markiert wird. Deshalb frage ich mich, was für wichtige Hinweise fehlen sollen.
GPI hat geschrieben:
NicTheQuick hat geschrieben:Außerdem funktioniert es scheinbar nicht mit ungespeicherten Codes. Oder ich mache was falsch.
Und ja, der Code muss erst gespeichert werden.
Damit es mit und ohne gespeichertem Code funktioniert, muss als Parameter nicht "%file" angegeben werden, sondern "%tempfile" (mit Anführungszeichen).

Re: Tool: CreatePreprocess

Verfasst: 15.11.2015 08:05
von GPI
Sicro hat geschrieben:Bei einem Fehler in einem Macro wird doch noch zusätzlich ein Fenster geöffnet ("Macro-Fehler"), in dem die fehlerhafte Zeile im Macro-Code markiert wird. Deshalb frage ich mich, was für wichtige Hinweise fehlen sollen.
Ich hatte es mehr als einmal, das das Fehler nur die Zeile des aufgerufenen Macros angegeben wurde und mehr nicht. Gerade bei Laufzeitfehler ist das nicht wirklich hilfreich.
Damit es mit und ohne gespeichertem Code funktioniert, muss als Parameter nicht "%file" angegeben werden, sondern "%tempfile" (mit Anführungszeichen).
Dann erwartet PB aber sämtliche Includes in Temp-Verzeichnis und damit keine Lösung.