I thought about a PB tool to let the compiler help us, here is what I came-up with.
Code: Select all
;/--------------------------------
;| Tool to help debugging Macro errors
;|
;| (c)HeX0R 2023
;|
;|
;| PB Tool Settings:
;| Commandline: Path + Filename of tool
;| Arguments: "%TEMPFILE" "%COMPILEFILE"
;| Working Directory:
;| Name: as you like
;| Trigger Event: Before Compile/Run
;| Wait until tool quits: [x]
;| Run Hidden: [ ]
;| Hide Editor: [x]
;|
;| Usage
;| The tool doesn't do anything, as long as it doesn't find the following comment somewhere at the top of the current source code
;| ;expandmacros
;|
;| When it finds that, it will interrupt compilation process and:
;| 1.) creates one large source code containing all includes and macros expanded
;| 2.) Open-up the external PB debugger to debug that huge source code
;| 3.) It will then show, where errors really happened
;|
;| Some bad things:
;| 1.) When the external debugger is finished, PB will go on with its own compilation and debugging process.
;| There doesn't seem to be any possibility to interrupt that (thought about ending with an End -1 or something, but that doesn't work)
;| 2.) Since the Macros are expanded within the source codes, you might have difficulties to recognize to which Macro the code really belongs
;| Would be cool, when the compiler would add the Macro name as comment, when using /PREPROCESS
;|
;| ToDo:
;| 1.) change extensions to support also other OS then Windows
;| 2.) error handling from compiler
;/--------------------------------
Procedure main()
Protected FileOut$, FileIn$, Compiler$, Line$, Commands$, Project$, tmpOut$, tmpExe$, Debugger$
Protected ExpandMacros, PID, Start
FileIn$ = ProgramParameter(0)
FileOut$ = ProgramParameter(1)
tmpExe$ = GetTemporaryDirectory() + "zzz_PB_Output.exe"
Compiler$ = GetEnvironmentVariable("PB_TOOL_Compiler")
Debugger$ = GetPathPart(Compiler$) + "PBDebugger.exe"
If FileIn$ And Compiler$
If ReadFile(0, FileIn$, #PB_UTF8)
ReadStringFormat(0)
While Eof(0) = 0
Line$ = ReadString(0)
If FindString(Line$, ";expandmacros", 1, #PB_String_NoCase) = 1
ExpandMacros = #True
ElseIf ExpandMacros
If FindString(Line$, "; IDE Options = PureBasic", 1, #PB_String_NoCase) = 1
Start = #True
ElseIf Start
If FindString(Line$, "; Optimizer", 1, #PB_String_NoCase) = 1
Commands$ + " /OPTIMIZER"
EndIf
If FindString(Line$, "; EnableThread", 1, #PB_String_NoCase) = 1
Commands$ + " /THREAD"
EndIf
If FindString(Line$, "; EnableXP", 1, #PB_String_NoCase) = 1
Commands$ + " /XP"
EndIf
If FindString(Line$, "; EnableAdmin", 1, #PB_String_NoCase) = 1
Commands$ + " /ADMINISTRATOR"
EndIf
If FindString(Line$, "; DPIAware", 1, #PB_String_NoCase) = 1
Commands$ + " /DPIAWARE"
EndIf
If FindString(Line$, "; EnableOnError", 1, #PB_String_NoCase) = 1
Commands$ + " /LINENUMBERING"
EndIf
If FindString(Line$, "; SubSystem", 1, #PB_String_NoCase) = 1
Commands$ + " /SUBSYSTEM " + #DQUOTE$ + Trim(StringField(Line$, 2, "=")) + #DQUOTE$
EndIf
If FindString(Line$, "; EnableCompileCount", 1, #PB_String_NoCase) = 1
Commands$ + " /CONSTANT " + #DQUOTE$ + "PB_Editor_CompileCount=" + Trim(StringField(Line$, 2, "=")) + #DQUOTE$
EndIf
If FindString(Line$, "; EnableBuildCount", 1, #PB_String_NoCase) = 1
Commands$ + " /CONSTANT " + #DQUOTE$ + "PB_Editor_BuildCount=" + Trim(StringField(Line$, 2, "=")) + #DQUOTE$
EndIf
If FindString(Line$, "; EnableExeConstant", 1, #PB_String_NoCase) = 1
Commands$ + " /CONSTANT " + #DQUOTE$ + "PB_Editor_CreateExecutable=0" + #DQUOTE$
EndIf
If FindString(Line$, "; Constant =", 1, #PB_String_NoCase) = 1
Commands$ + " /CONSTANT " + #DQUOTE$ + Trim(RemoveString(StringField(Line$, 2, "="), "#")) + "=" + Trim(StringField(Line$, 3, "=")) + #DQUOTE$
EndIf
EndIf
EndIf
Wend
CloseFile(0)
EndIf
EndIf
If ExpandMacros
tmpOut$ = GetPathPart(FileOut$) + "zzz_" + GetFilePart(FileOut$)
Commands$ + " /DEBUGGER"
;First step, make one huge PB file, containing all includes and macros expanded in the code
PID = RunProgram(Compiler$, #DQUOTE$ + FileIn$ + #DQUOTE$ + Commands$ + " /PREPROCESS " + #DQUOTE$ + tmpOut$ + #DQUOTE$, "", #PB_Program_Read | #PB_Program_Hide | #PB_Program_Open)
If PID
While ProgramRunning(PID)
If AvailableProgramOutput(PID)
Result$ + ReadProgramString(PID) + #LF$
EndIf
Delay(5)
Wend
CloseProgram(PID)
Result$ + #CRLF$ + "----" + #CRLF$
;Scond step, compile this source
PID = RunProgram(Compiler$, #DQUOTE$ + tmpOut$ + #DQUOTE$ + Commands$ + " /OUTPUT " + #DQUOTE$ + tmpExe$ + #DQUOTE$, "", #PB_Program_Read | #PB_Program_Hide | #PB_Program_Open)
If PID
While ProgramRunning(PID)
If AvailableProgramOutput(PID)
Result$ + ReadProgramString(PID) + #LF$
EndIf
Delay(5)
Wend
CloseProgram(PID)
EndIf
Result$ + #CRLF$ + "----" + #CRLF$
;third step, call external Debugger
RunProgram(Debugger$, #DQUOTE$ + tmpExe$ + #DQUOTE$, "", #PB_Program_Wait)
EndIf
;MessageRequester("Info", Result$)
;[optional]
;remove the files we've created
EndIf
EndProcedure
main()