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