$APPTYPE GUI
$TYPECHECK ON
$OPTION ICON "RapidDBG.ico"
$INCLUDE "Rapidq2.inc"
$DEFINE TIDY_TEMP_FILES
$DEFINE COMP_ONLY 1
$DEFINE RUN_USER 2
$DEFINE RUN_DEBUG 3
CONST CRLF=CHR$(13)+CHR$(10)
CONST QU=CHR$(34)
$RESOURCE DebugData AS "RapidDBG.dat"
$RESOURCE ProgIcon AS "RapidDBG.ico"
$RESOURCE ButnPics AS "RapidDBG.bmp"
DECLARE FUNCTION WaitOnCompile LIB "kernel32" ALIAS "WaitForSingleObject" (hHandle AS LONG, _
dwMilliseconds AS LONG) AS LONG
DECLARE FUNCTION fbParserVersion LIB "fbDBGParser" ALIAS "fbParserVersion@4" (lpRetString AS LONG) AS INTEGER
DECLARE FUNCTION fbParseFile LIB "fbDBGParser" ALIAS "fbParseFile@20" (lpSrcFile AS LONG, _
lpDataFile AS LONG, lpInitData AS LONG, lpRetString AS LONG, buflen AS INTEGER) AS INTEGER
DECLARE SUB DbgNoClose(Action AS INTEGER)
DECLARE FUNCTION TRIM$(srcLine AS STRING) AS STRING
DECLARE SUB Initialise
DECLARE SUB GetEnvironment
DECLARE SUB LoadEnvironment
DECLARE SUB KillDebugEXE
DECLARE SUB DbgError(ErrNum AS INTEGER)
DECLARE SUB GotResponse(Sender AS QBUTTON)
DECLARE SUB WaitResponse(msg AS STRING, msgType AS INTEGER)
DECLARE SUB TestUserSource
DECLARE SUB CreateDbgTarget
DECLARE SUB CreateDbgExe
DECLARE SUB RunDbgExe
DEFSTR VERSION
DEFINT CommandParm
DEFSTR rcPath
DEFSTR incPath
DEFSTR libPath
DEFSTR iniFile
DEFSTR srcFile
DEFSTR dbgFile
DEFSTR PreSetBrkPoints
DIM SrcStream AS QMEMORYSTREAM
DIM DatStream AS QMEMORYSTREAM
DIM tmpStream AS QMEMORYSTREAM
CREATE DbgForm AS QFORM
Height=200
Width=500
DelBorderIcons(2)
BorderStyle=1
Font.Size=9
Font.AddStyles fsBold
Center
CAPTION="RapidDBG "+VERSION
OnClose=DbgNoClose
CREATE RichEd AS QRICHEDIT
Align=5
HideScrollBars=False
ScrollBars=ssVertical
PlainText=True
ReadOnly=True
Alignment=0
HideSelection=True
END CREATE
CREATE DirTree AS QDIRTREE
Align=5
Visible=False
InitialDir=LEFT$(Application.Path,3)
END CREATE
CREATE OKButn AS QBUTTON
Top=DbgForm.ClientHeight-OKButn.Height
Left=(DbgForm.ClientWidth-OKButn.Width)\2
CAPTION="Set"
Tag=0
Visible=False
OnClick=GotResponse
END CREATE
END CREATE
Initialise
TestUserSource
CreateDbgTarget
CreateDbgExe
RunDbgExe
DbgError(0)
SUB DbgNoClose(Action)
Action=False
END SUB
FUNCTION TRIM$(srcLine)
Result=RTRIM$(LTRIM$(srcLine))
END FUNCTION
SUB CreateDbgTarget
DEFINT i, retVal
DEFSTR buf, tstr
DIM tFile AS QFILESTREAM
RichEd.AddStrings "Parsing "+srcFile
buf=SPACE$(256)
SrcStream.CLOSE
tFile.OPEN (srcFile, fmOpenRead)
SrcStream.CopyFrom(tFile,0)
SrcStream.WriteNum(0,4)
tFile.CLOSE
DOEVENTS
SrcStream.Position=0
DatStream.CLOSE
DatStream.ExtractRes(Resource(0))
DatStream.WriteNum(0,4)
DatStream.Position=0
$IFDEF TIDY_TEMP_FILES
tstr="$DEFINE TIDY_TEMP_FILES~"
$ELSE
tstr="$UNDEF TIDY_TEMP_FILES~"
$ENDIF
tstr=tstr+srcFile+"~"
tstr=tstr+Application.Path+"\~"
tstr=tstr+PreSetBrkPoints+"~"
tstr=tstr+STR$(DbgForm.Left)+"~"
tstr=tstr+STR$(DbgForm.Top+DbgForm.Height-50)+"~"
retVal=fbParseFile(SrcStream.Pointer, DatStream.Pointer, VARPTR(tstr), VARPTR(buf), LEN(buf))
SrcStream.CLOSE: DatStream.CLOSE: tmpStream.CLOSE
IF retVal=0 THEN
tstr="ERROR: CreateDbgTarget()"+CRLF+"Reason:"+CRLF+RTRIM$(buf)+CRLF+"Terminating!"
MESSAGEBOX(tstr,"RapidDBG "+VERSION,&H10)
Application.Terminate
END IF
$IFNDEF TIDY_TEMP_FILES
MESSAGEBOX(buf,"Information",&H40)
$ENDIF
buf=" ": tstr=" "
END SUB
FUNCTION HasLineNumbers() AS INTEGER
DEFINT i
DEFSTR tstr
DIM tFile AS QFILESTREAM
tmpStream.CLOSE
tFile.OPEN(srcFile,fmOpenRead)
tmpStream.CopyFrom(tFile,0)
tFile.CLOSE
DOEVENTS
tmpStream.Position=0
FOR i=1 TO 32
tstr=tmpStream.ReadLine
tstr=REPLACESUBSTR$(tstr,CHR$(9)," ")
IF LEFT$(UCASE$(tstr),4)<>"REM " AND LEFT$(tstr,1)<>"'" THEN
tstr=FIELD$(tstr," ",1)
IF VAL(tstr)>0 THEN
Result=True
EXIT FUNCTION
END IF
END IF
NEXT i
Result=False
END FUNCTION
SUB RunUserProgram
DEFSTR tgtFile
tgtFile=LEFT$(srcFile,RINSTR(srcFile,"."))+"EXE"
IF FILEEXISTS(tgtFile)=0 THEN
MESSAGEBOX(tgtFile+" - File does not exists!","RapidDBG "+VERSION,&H10)
ELSE
RUN tgtFile
END IF
Application.Terminate
END SUB
FUNCTION CompileFile(FileStr AS STRING) AS INTEGER
DEFINT size
DEFLNG PID
DEFSTR tgtFile, RQCompile
DIM File AS QFILESTREAM
tgtFile=LEFT$(FileStr,RINSTR(FileStr,"."))+"EXE"
RQCompile=QU+rcPath+"\RC.EXE"+QU+" -r "+QU+"-I"+incPath+QU+" "
RQCompile=RQCompile+QU+"-L"+libPath+QU+" "+QU+FileStr+QU+" "+QU+tgtFile+QU
PID=SHELL(RQCompile,0)
WaitOnCompile(PID,120000)
IF FILEEXISTS(tgtFile) THEN
File.OPEN(tgtFile,fmOpenRead)
size=File.Size
File.CLOSE
DOEVENTS
IF size>0 THEN
Result=True
ELSE
Result=False
END IF
ELSE
Result=False
END IF
END FUNCTION
SUB TestUserSource
DEFINT i
DEFSTR tstr, RQDumpStr
DIM tFile AS QFILESTREAM
RichEd.AddStrings "Checking syntax of "+srcFile
IF CommandParm=RUN_DEBUG THEN
IF HasLineNumbers() THEN DbgError(1)
END IF
RQDumpStr=LEFT$(srcFile,RINSTR(srcFile,"\"))+"DUMP.$$$"
IF CompileFile(srcFile) THEN
KILL RQDumpStr
DOEVENTS
IF CommandParm=RUN_USER THEN
RichEd.AddStrings "Running program..."
RunUserProgram
ELSE
tstr=LEFT$(srcFile,RINSTR(srcFile,"."))+"EXE"
KILL tstr
DOEVENTS
IF CommandParm=COMP_ONLY THEN
RichEd.AddStrings "Success!"
MESSAGEBOX("Your code compiles ok!","RapidDBG "+VERSION,&H40)
Application.Terminate
END IF
END IF
ELSE
tFile.OPEN(RQDumpStr,fmOpenRead)
tstr=tFile.ReadLine
tstr="Rapid-Q Compiler Beta by William Yu"+CRLF
tstr=tstr+"Copyright 1999-2000"+CRLF+CRLF
tstr=tstr+"______________________________________________"+CRLF
FOR i=1 TO tFile.LineCount-1
tstr=tstr+tFile.ReadLine+CHR$(13)
NEXT i
tstr=tstr+CRLF
tstr=tstr+"____________________.o0o.______________________"+CRLF
tFile.CLOSE
DOEVENTS
MESSAGEBOX(tstr,"RapidDBG "+VERSION,&H10)
Application.Terminate
END IF
END SUB
SUB CreateDbgExe
DEFINT i
DEFSTR tstr, RQDumpStr
DIM tFile AS QFILESTREAM
RichEd.AddStrings "Generating debug executable"
DOEVENTS
RQDumpStr=LEFT$(dbgFile,RINSTR(dbgFile,"\"))+"DUMP.$$$"
IF CompileFile(dbgFile)=False THEN
tFile.OPEN(RQDumpStr,fmOpenRead)
tstr="_____________### RapidDBG FAILURE ###_____________"+CRLF+CRLF
FOR i=1 TO tFile.LineCount
tstr=tstr+tFile.ReadLine+CHR$(13)
NEXT i
tstr=tstr+CRLF+"Please advise the author of this problem."+CRLF
tstr=tstr+"Please include an extract of the code"+CRLF
tstr=tstr+"around the error line in file:"++CRLF+dbgFile+CRLF
tstr=tstr+"_______________________.o0o._______________________"+CRLF
tFile.CLOSE
DOEVENTS
RichEd.AddStrings "### RapidDBG FAILURE ###"
MESSAGEBOX(tstr,"RapidDBG "+VERSION,&H10)
Application.Terminate
END IF
KILL RQDumpStr
DOEVENTS
END SUB
SUB RunDbgExe
DEFSTR tgtFile
RichEd.AddStrings "Running debugger...",""
DOEVENTS
SLEEP.MS 250
tgtFile=LEFT$(dbgFile,RINSTR(dbgFile,"."))+"EXE"
IF FILEEXISTS(tgtFile) THEN
RUN tgtFile
Application.Terminate
ELSE
DbgError(8)
END IF
END SUB
SUB DbgError(errnum)
DEFSTR tstr, msg="ERR #"+STR$(errnum)+CRLF
DEFINT msgIcon=&h10
SELECT CASE errnum
CASE 0: tstr="RapidDBG will now terminate": msg="": msgIcon=&h40
CASE 1: tstr="Sorry, line numbers are not supported in this version!"
CASE 2: tstr="Environment ini file corrupt!": msgIcon=&h20
CASE 3:
tstr="USAGE:"+CRLF+"RapidDBG <option> <source file> [-b <Breakpoints>]"+CRLF+CRLF
tstr=tstr+"Source file must include full path, and be of type bas or rqb"+CRLF+CRLF
tstr=tstr+"options:"+CRLF+" -c/-C Compile the source file, check for errors"+CRLF
tstr=tstr+" -r/-R Compile then run the source file"+CRLF
tstr=tstr+" -d/-D Compile the source file with debug code, run debugger"+CRLF+CRLF
tstr=tstr+" -b/-B Optional preset breakpoints used with -d/-D"+CRLF
tstr=tstr+" String of comma separated line numbers"+CRLF+CRLF
msgIcon=&h40
CASE 4: tstr="Your source file is invalid or non-existent"
CASE 5: tstr="Expecting BAS or RQB source file ONLY!"
CASE 6: tstr="Cannot find parser dll": msgIcon=&h20
CASE 7: tstr="Problem loading parser dll": msgIcon=&h20
CASE 8: tstr="RunDbgExe() - Internal Error!"
CASE ELSE
tstr="Unidentified Error!!!!"
END SELECT
msg=msg+tstr
MESSAGEBOX(msg,"RapidDBG"+VERSION, msgIcon)
Application.Terminate
END SUB
SUB KillDebugEXE
DEFSTR tgtFile
RichEd.Clear
RichEd.AddStrings "RapidDBG "+VERSION+" - Terminating"
DOEVENTS
SLEEP.MS 1000
tgtFile=UCASE$(TRIM$(COMMAND$(2)))
KILL tgtFile
WHILE FILEEXISTS(tgtFile)
DOEVENTS
SLEEP.MS 100
KILL tgtFile
WEND
Application.Terminate
END SUB
SUB GotResponse(Sender)
Sender.Tag=1
END SUB
SUB WaitResponse(msg, msgType)
OKButn.Tag=0
OKButn.Visible=True
MESSAGEBOX(msg,"RapidDBG "+VERSION,msgType)
WHILE OKButn.Tag=0
DOEVENTS
WEND
OKButn.Tag=0
OKButn.Visible=False
END SUB
SUB GetEnvironment
DIM tFile AS QFILESTREAM
iniFile=Application.Path+"\RapidDBG.ini"
DbgForm.CAPTION="Pre-set your RapidQ environment"
DbgForm.Show
DirTree.Visible=True
WaitResponse("Set path to RC.EXE",&h20)
rcPath=LEFT$(DirTree.Directory,LEN(DirTree.Directory)-1)
WaitResponse("Set path to INCLUDE files",&h20)
incPath=LEFT$(DirTree.Directory,LEN(DirTree.Directory)-1)
WaitResponse("Set path to LIB files",&h20)
libPath=LEFT$(DirTree.Directory,LEN(DirTree.Directory)-1)
DirTree.Visible=False
DbgForm.Visible=False
tFile.OPEN(iniFile,fmCreate)
tFile.WriteLine(rcPath)
tFile.WriteLine(incPath)
tFile.WriteLine(libPath)
tFile.CLOSE
DOEVENTS
END SUB
SUB LoadDbgEnvironment
DIM tFile AS QFILESTREAM
iniFile=Application.Path+"\RapidDBG.ini"
tmpStream.Position=0
tFile.OPEN(iniFile,fmOpenRead)
tmpStream.CopyFrom(tFile,0)
tFile.CLOSE
IF tmpStream.LineCount<>3 THEN
KILL iniFile
DbgError(2)
END IF
DOEVENTS
tmpStream.Position=0
rcPath=tmpStream.ReadLine
incPath=tmpStream.ReadLine
libPath=tmpStream.ReadLine
tmpStream.CLOSE
END SUB
SUB LoadIdeEnvironment
DEFINT i
DEFSTR tstr, token, drv
DIM tFile AS QFILESTREAM
drv=FIELD$(Application.Path,"\",1)
tstr=Application.Path
tstr=LEFT$(tstr,RINSTR(tstr,"\"))+"Freeq.ini"
IF FILEEXISTS(tstr) THEN
iniFile=tstr
ELSE
iniFile=Application.Path+"\Freeq.ini"
END IF
tmpStream.CLOSE
tFile.OPEN(iniFile,fmOpenRead)
tmpStream.CopyFrom(tFile,0)
tFile.CLOSE
DOEVENTS
tmpStream.Position=0
FOR i=1 TO tmpStream.LineCount
tstr=tmpStream.ReadLine
token=TRIM$(UCASE$(FIELD$(tstr,"=",1)))
SELECT CASE token
CASE "COMPILERPATH": rcPath=TRIM$(FIELD$(tstr,"=",2))
CASE "COMPILERLIBPATH": libPath=TRIM$(FIELD$(tstr,"=",2))
CASE "COMPILERINCPATH": incPath=TRIM$(FIELD$(tstr,"=",2))
END SELECT
NEXT i
tmpStream.CLOSE
rcPath=REPLACESUBSTR$(rcPath,"/","\")
IF INSTR(rcPath,":")=0 THEN
IF LEFT$(rcPath,1)<>"\" THEN rcPath="\"+rcPath
rcPath=drv+rcPath
END IF
IF UCASE$(RIGHT$(rcPath,3))="EXE" THEN
rcPath=LEFT$(rcPath,RINSTR(rcPath,"\")-1)
END IF
libPath=REPLACESUBSTR$(libPath,"/","\")
IF INSTR(libPath,":")=0 THEN
IF LEFT$(libPath,1)<>"\" THEN libPath="\"+libPath
libPath=drv+libPath
END IF
IF RIGHT$(libPath,1)="\" THEN libPath=LEFT$(libPath,LEN(libPath)-1)
incPath=REPLACESUBSTR$(incPath,"/","\")
IF INSTR(incPath,":")=0 THEN
IF LEFT$(incPath,1)<>"\" THEN incPath="\"+incPath
incPath=drv+incPath
END IF
IF RIGHT$(incPath,1)="\" THEN incPath=LEFT$(incPath,LEN(incPath)-1)
END SUB
SUB CheckEnvironment
DEFLNG hDll
DEFSTR tstr
tstr=Application.Path
tstr=LEFT$(tstr,RINSTR(tstr,"\"))+"Freeq.ini"
IF FILEEXISTS(tstr) OR FILEEXISTS(Application.Path+"\Freeq.ini") THEN
LoadIdeEnvironment
ELSEIF FILEEXISTS(Application.Path+"\RapidDBG.ini") THEN
LoadDbgEnvironment
ELSE
GetEnvironment
END IF
IF FILEEXISTS(Application.Path+"\fbDBGParser.dll")=0 THEN
IF FILEEXISTS(LibPath+"\fbDBGParser.dll")=0 THEN
DbgError(6)
ELSE
hDll=LoadLibrary(LibPath+"\fbDBGParser.dll")
IF hDll=0 THEN DbgError(7)
END IF
END IF
END SUB
FUNCTION CheckForBreakpoints() AS STRING
DEFSTR tstr
tstr=""
IF (COMMANDCOUNT=4) AND (UCASE$(TRIM$(COMMAND$(3)))="-B") THEN
tstr=TRIM$(COMMAND$(4))
END IF
Result=tstr
END FUNCTION
SUB LoadSourceFile
DIM fDialog AS QOPENDIALOG
DEFSTR fName, tgtFolder
srcFile=""
dbgFile=""
fDialog.CAPTION="Load Source File"
fDialog.FileName=""
fDialog.InitialDir=Application.Path
fDialog.Filter="Source Files (*.bas *.rqb)|*.bas;*.rqb"
IF fDialog.EXECUTE THEN
srcFile=fDialog.FileName
fName=RIGHT$(srcFile,LEN(srcFile)-RINSTR(srcFile,"\"))
fName=LEFT$(fName,RINSTR(fName,"."))
tgtFolder=LEFT$(srcFile,RINSTR(srcFile,"\"))
dbgFile=tgtFolder+"~"+fName+"bas"
CommandParm=RUN_DEBUG
ELSE
RichEd.AddStrings "No source file selected!"
DbgError(0)
END IF
END SUB
SUB Initialise
DEFSTR tstr, buf, tgtFolder
SetWindowLong(DbgForm.Handle, -8, 0)
SetWindowLong(Application.Handle, -8, DbgForm.Handle)
DbgForm.Show
RichEd.AddStrings "Initialising..."
CheckEnvironment
buf=SPACE$(16)
IF fbParserVersion(VARPTR(buf)) THEN
VERSION=FIELD$(buf,CHR$(0),1)
DbgForm.CAPTION="RapidDBG "+VERSION
ELSE
tstr="Failed to get dll version info!"+CRLF+"RapidDBG terminating"
MESSAGEBOX(tstr,"RapidDBG",&H10)
Application.Terminate
END IF
IF COMMANDCOUNT=0 THEN
LoadSourceFile
ELSE
IF COMMANDCOUNT<2 THEN DbgError(3)
tstr=UCASE$(TRIM$(COMMAND$(1)))
SELECT CASE tstr
CASE "-C": CommandParm=COMP_ONLY
CASE "-R": CommandParm=RUN_USER
CASE "-D"
CommandParm=RUN_DEBUG
PreSetBrkPoints=CheckForBreakpoints
CASE "-X": KillDebugEXE
CASE ELSE
DbgError(3)
END SELECT
srcFile=TRIM$(COMMAND$(2))
srcFile=REPLACESUBSTR$(srcFile,"/","\")
IF FILEEXISTS(srcFile)=0 THEN DbgError(4)
tstr=UCASE$(RIGHT$(srcFile,LEN(srcFile)-RINSTR(srcFile,".")))
IF (tstr<>"BAS") AND (tstr<>"RQB") THEN DbgError(5)
tgtFolder=LEFT$(srcFile,RINSTR(srcFile,"\")-1)
CHDIR tgtFolder
tgtFolder=tgtFolder+"\"
tstr=srcFile-tgtFolder
tstr=LEFT$(tstr,RINSTR(tstr,"."))
dbgFile=tgtFolder+"~"+tstr+"bas"
END IF
IF FILEEXISTS(Application.Path+"\RapidDBG.ico")=0 THEN
EXTRACTRESOURCE Resource(1),Application.Path+"\RapidDBG.ico"
DOEVENTS
END IF
IF FILEEXISTS(Application.Path+"\RapidDBG.bmp")=0 THEN
EXTRACTRESOURCE Resource(2),Application.Path+"\RapidDBG.bmp"
DOEVENTS
END IF
END SUB
|
|