Seite 1 von 1

Anzahl der Programmzeilen ermitteln

Verfasst: 22.08.2014 17:14
von SBond
Hallo Leute.

Gibt es eine einfache Möglichkeit, die Programmzeilen zu ermitteln? Ich meine damit die Anzahl, die PureBasic auch beim Kompilieren oder bei der Syntax-Überprüfung ausgibt:
[17:10:49] [COMPILER] Syntax check finished (20244 lines)

In der PB-Hilfe bin ich auf folgendes gestoßen: #PB_Compiler_Line
Allerdings gibt diese Konstante nur die aktuelle Zeile zuück.

Habt ihr eine Idee?

Re: Anzahl der Programmzeilen ermitteln

Verfasst: 22.08.2014 17:26
von NicTheQuick
An welcher Stelle möchtest du das denn wissen? Zur Laufzeit? Zur Übersetzungszeit? Innerhalb eines IDE-Tools?

Re: Anzahl der Programmzeilen ermitteln

Verfasst: 22.08.2014 17:49
von SBond
Es wäre schön, wenn mir diese Information während der Laufzeit zur Verfügung steht.

Ich möchte in der lauffähigen Anwendung einige Informationen über den Quellcode einbetten. Das sind z.B. Informationen, über die verwendeten Module, Modulversionen. Die Anzahl der Programmzeilen (des kompletten Programms) wollte ich auch gerne mit aufnehmen.

viele Grüße,
SBond

Re: Anzahl der Programmzeilen ermitteln

Verfasst: 22.08.2014 17:58
von NicTheQuick
Wäre das eine Variante die dir gefällt?

Code: Alles auswählen

Global programLines.i
Gosub getProgramLines

; Hier
; der
; komplette
; Code.

Debug programLines

; Hier
; noch
; mehr
; Code.

End
getProgramLines:
programLines = #PB_Compiler_Line + 1
Return
Ansonsten wäre es am einfachsten, sich ein Tool zu schreiben, was das erledigt und automatisch die ermittelten Werte in Konstanten in den Code einfügt, bevor er kompiliert wird.

Re: Anzahl der Programmzeilen ermitteln

Verfasst: 22.08.2014 18:09
von SBond
...das klappt leider nicht bei mir <)

Ich habe bei mir Programmcode ausgelagert, die ich in der Hauptdatei inkludiere. Diese werden von #PB_Compiler_Line nicht mitgezählt, sondern nur die Zeilen der aktuellen Datei.

Naja... notfalls muss ich den Wert immer von Hand in eine Variable eintragen.
Nochmals danke für deinen Ratschlag.

viele Grüße,
SBond

Re: Anzahl der Programmzeilen ermitteln

Verfasst: 22.08.2014 23:04
von Sicro
Mit einem Werkzeug für die Purebasic-IDE lässt sich das realisieren:

Code: Alles auswählen

; ######################################################################
; Tool zweimal zu den Werkzeugen hinzufügen!
;
; Werkzeug-Einstellungen:
;   Argumente: "%FILE %COMPILEFILE" (ohne "") eintragen
;   Checkbox "Warten bis zum Beenden des Werkzeugs" anhaken
;   Checkbox "Werkzeug vom Hauptmenü verstecken" anhaken
;   1. Eintrag >> Ereignis auf "Vor dem Erstellen des Executable" setzen
;   2. Eintrag >> Ereignis auf "Vor dem Kompilieren/Starten" setzen
; ######################################################################

Global NewList Macros.s()
Global CountOfAllCodeLines
Global CodeFileFolderPath.s  = GetPathPart(ProgramParameter(0)) ; GetPathPart(%FILE)
Global CompileCodeFilePath.s = ProgramParameter(1)              ; %COMPILEFILE

Procedure.s RemoveLeadingTabsAndWhiteSpacesFromString(String.s)
  Repeat
    If Left(String, 1) = " "
      String = LTrim(String)
    ElseIf Left(String, 1) = #TAB$
      String = LTrim(String, #TAB$)
    Else
      Break
    EndIf
  ForEver
  ProcedureReturn String
EndProcedure

Procedure.i IsAbsolutePath(Path.s)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows
      If Mid(Path, 2, 1) = ":"
        ProcedureReturn #True
      EndIf
    CompilerDefault
      If Left(Path, 1) = "/"
        ProcedureReturn #True
      EndIf
  CompilerEndSelect
EndProcedure

Procedure.s AddEndSlash(Path.s)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows
      If Right(Path, 1) <> "\": Path + "\": EndIf
    CompilerDefault
      If Right(Path, 1) <> "/": Path + "/": EndIf
  CompilerEndSelect
  ProcedureReturn Path
EndProcedure

Procedure ScanPBCodeFile(FilePath.s)
  Protected.i File, BOM
  Protected.s LineText
  
  File = ReadFile(#PB_Any, FilePath, #PB_File_SharedRead)
  If IsFile(File)
    BOM = ReadStringFormat(File)
    
    While Not Eof(File)
      LineText = ReadString(File, BOM)
      
      ; IDE-Einstellungen am Code-Ende überspringen
      If Left(LineText, 25) = "; IDE Options = PureBasic"
        Continue
      EndIf
      
      LineText = RemoveLeadingTabsAndWhiteSpacesFromString(LineText) ; evtl. Tabs oder Leerzeichen entfernen
      CountOfAllCodeLines + 1
      
      ; Macros auslesen
      If Left(LCase(LineText), 5) = "macro"
        LineText = Mid(LineText, 6) ; "macro" entfernen
        LineText = RemoveLeadingTabsAndWhiteSpacesFromString(LineText) ; evtl. Tabs oder Leerzeichen entfernen
        AddElement(Macros())
        Macros() = LineText
        Continue
      EndIf
      
      ; IncludePath auslesen
      If Left(LCase(LineText), 11) = "includepath"
        LineText = Mid(LineText, 12)                                   ; "includepath" entfernen
        LineText = RemoveLeadingTabsAndWhiteSpacesFromString(LineText) ; evtl. Tabs oder Leerzeichen entfernen
        LineText = Mid(LineText, 2)                                    ; Anführungszeichen entfernen
        LineText = Left(LineText, FindString(LineText, #DQUOTE$) - 1)  ; Anführungszeichen am Ende und den Rest entfernen
        If IsAbsolutePath(LineText)
          FilePath = AddEndSlash(LineText)
        Else
          If FilePath = CompileCodeFilePath
            FilePath = CodeFileFolderPath
          EndIf
          FilePath = AddEndSlash(GetPathPart(FilePath) + LineText)
        EndIf
        Continue
      EndIf
      
      ; IncludeFile und XIncludeFile auslesen
      ;TODO: XInclude: kein mehrfaches Hinzufügen beachten
      LineText = ReplaceString(LineText, "XIncludeFile", "IncludeFile")
      If Left(LCase(LineText), 11) = "includefile"
        LineText = Mid(LineText, 12) ; "includefile" entfernen
        LineText = RemoveLeadingTabsAndWhiteSpacesFromString(LineText) ; evtl. Tabs oder Leerzeichen entfernen
        LineText = Mid(LineText, 2)                                    ; Anführungszeichen entfernen
        LineText = Left(LineText, FindString(LineText, #DQUOTE$) - 1)  ; Anführungszeichen am Ende und den Rest entfernen
        If IsAbsolutePath(LineText)
          ScanPBCodeFile(LineText)                                     ; Include-File rekursive auslesen
        Else
          If FilePath = CompileCodeFilePath
            FilePath = CodeFileFolderPath
          EndIf
          ScanPBCodeFile(GetPathPart(FilePath) + LineText)             ; Include-File rekursive auslesen
        EndIf
      EndIf
    Wend
    
    CloseFile(File)
  EndIf
EndProcedure

Define.i File, BOM
Define.s FileContent, Macros

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    #LineFeed = #CRLF$
  CompilerDefault
    #LineFeed = #LF$
CompilerEndSelect

ScanPBCodeFile(CompileCodeFilePath)

File = ReadFile(#PB_Any, CompileCodeFilePath, #PB_File_SharedRead)
If IsFile(File)
  BOM = ReadStringFormat(File)
  FileContent = ReadString(File, BOM | #PB_File_IgnoreEOL)
  CloseFile(File)
  
  ; Variable "%CountOfAllCodeLines%" ersetzen
  FileContent = ReplaceString(FileContent, "%CountOfAllCodeLines%", Str(CountOfAllCodeLines))
  
  ; Variable "%ListOfAllMacros%" ersetzen
  ForEach Macros()
    Macros + Macros() + #DQUOTE$ + " + #CRLF$ + " + #LineFeed + #DQUOTE$
  Next
  Macros = RTrim(Macros, " + #CRLF$ + " + #LineFeed + #DQUOTE$)
  FileContent = ReplaceString(FileContent, "%ListOfAllMacros%", Macros)
  
  ; Änderungen in Datei schreiben
  File = CreateFile(#PB_Any, CompileCodeFilePath)
  If IsFile(File)
    WriteStringFormat(File, BOM)
    WriteString(File, FileContent, BOM)
    CloseFile(File)
  EndIf
EndIf
Test-Code:

Code: Alles auswählen

Macro TestMacro1
  "test"
EndMacro

Macro TestMacro2
  "test"
EndMacro

z = a + b

;IncludeFile "TestCode2.pbi"

MessageRequester("Code-Informationen", "Code-Zeilen: %CountOfAllCodeLines%" + #CRLF$ + #CRLF$ + "Enhaltene Macros:" + #CRLF$ + "%ListOfAllMacros%")
liefert die Ausgabe:
Code-Zeilen: 13

Enhaltene Macros:
TestMacro1
TestMacro2
Include-Dateien können wieder welche enthalten (Stichwort: rekursiv)

Update 24.08.14
* Rekursiver Scan der Include-Dateien funktioniert nun korrekt
* IncludePath-Unterstützung hinzugefügt
* Pfadangabe von IncludePath und (X)IncludeFile kann nun auch absolut sein

Re: Anzahl der Programmzeilen ermitteln

Verfasst: 23.08.2014 13:38
von SBond
cool.

vielen Dank. Die rekursive Suche scheint zwar nicht zu funktionieren, aber damit bekomme ich es bestimmt gelöst. Mit den Werkzeugen habe ich in PB noch nie gearbeitet. Dennoch scheint es genau das richtige zu sein.
...jetzt weiß ich wie ich da rangehe

vielen Dank für eure Hilfe <)

Re: Anzahl der Programmzeilen ermitteln

Verfasst: 23.08.2014 20:53
von Sicro
SBond hat geschrieben:Die rekursive Suche scheint zwar nicht zu funktionieren [...]
Ohje, da hast du Recht. Die "%COMPILEFILE"-Datei wird im Temp-Verzeichnis erstellt und da ich den Pfad zur Include-Datei relativ von dieser Datei zusammenbaue, wird die Include-Datei relativ vom Temp-Verzeichnis gesucht. Beim Testen hat alles prima geklappt, weil ich die Include-Datei im Temp-Verzeichnis erstellt hatte. Ich werde den Code nachher korrigieren.
SBond hat geschrieben:Mit den Werkzeugen habe ich in PB noch nie gearbeitet.
Ging mir ähnlich, daher wollte ich mich damit jetzt mal intensiver beschäftigen.