' xref.bas - a cross reference utility for Liberty Basic and similar' Author: Ken B Smith - Wattle Downs, Auckland Jun 2011''' This program is free software: you can redistribute it and/or modify' it under the terms of the GNU General Public License as published by' the Free Software Foundation, either version 3 of the License, or' (at your option) any later version.'' This program is distributed in the hope that it will be useful,' but WITHOUT ANY WARRANTY; without even the implied warranty of' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the' GNU General Public License for more details.' You should have received a copy of the GNU General Public License' along with this program. If not, see <http://www.gnu.org/licenses/>.' Date: 26/13/11' 27/6/11 Based on IQPDF text conversion module' 28/6/11 Removed snag with showing words in quotes in readascii' 28/6/11 Tidied up the aligment on listing' 04/7/11 Added Functions to show as 'F' and Function defined variables as 'f' - for Will !'global maxinput ' Number of files accepted on filelist
maxinput =40dim filedata$(maxinput,2)' (x,0) - filename ! (x,1) - size ! (x,2) = datedim info$(40,40)dim BASname$(maxinput)' These are decode variables' dim results(2,maxinput) ' hold the top 20 results from upto 20 filedim wordarray$(5000,2)' the structure will be strange : 0 = word : 1 = line/line/line/line/line - line numbers as 5 byte dec : 2 is variable type G etc' linenumber + 11111 + (len(word) * 11) - ready for main program directly.dim stats(10)' stats(0) = total line count / stats(1) = totalwords / stats(2) = total word count / stats(3) = Highest line count on a word' 6 bytes hex = totalwords / 4 bytes hex largest word count / 4 bytes hex highest line count on a wordglobal wordfound ' flag 0 = falseglobal wordcount ' word count on a lineglobal maxwordcount ' words in a documentglobal totalwords, maxperline
global maxperline
global targetword$ ' word to be insertedglobal targetline ' line number to go in the string if not already thereglobal fileIs$ ' What file are we working on ?global Stimerval ' Start timerglobal Etimerval ' End timerglobal BASTxt$, BASIdx$, BASFile$, BAScount
global filesize
global filedate$
global t$
global LBkey$ ' all the Liberty reserved words and variablesglobal legalchr$ ' string holding chr$ allowedglobal wordplace
global longestword
global metatagword
global metaid$ ' meta word IDglobal funcdefline ' holder for line number where a function definedglobal Qlisting ' True or False for listing on top of Xrefglobal Qnumbers ' do you want line numbers with that ?
LBkey$ =" abs acs append as asc and asn atn backgroundcolor$ beep binary bmpbutton bmpsave boolean button call "
LBkey$ = LBkey$ +" callback calldll case checkbox chr$ close cls colordialog combobox comboboxcolor$ commandline$ "
LBkey$ = LBkey$ +" confirm cos cursor data date$ dechex$ defaultdir$ dialog dialog_fs dialog_modal dialog_nf dialog_nf_modal "
LBkey$ = LBkey$ +" dialog_nf_fs dim displayheight displaywidth dll do drives$ dword dump else end eof err error err$ eval "
LBkey$ = LBkey$ +" eval$ exit exp field filedialog files fontdialog end for foregroundcolor$ function get gettrim global "
LBkey$ = LBkey$ +" gosub goto graphics graphics_fs graphics_fs_nsb graphics_nsb graphics_nf_nsb graphicbox groupbox hbmp "
LBkey$ = LBkey$ +" hexdec hwnd if inkey$ inp input input$ inputto$ instr int joy1x joy1y joy1z joy1button1 joy1button2 joy2x "
LBkey$ = LBkey$ +" joy2y joy2z joy2button1 joy2button2 kill left$ len let line listbox listboxcolor$ loadbmp locate loc "
LBkey$ = LBkey$ +" lof log long loop lower$ lprint lr maphandle max menu midipos mid$ min mkdir mod name next nomainwin "
LBkey$ = LBkey$ +" notice on open or out output platform$ playmidi playwave popupmenu print printerdialog printerfont$ prompt "
LBkey$ = LBkey$ +" ptr put radiobutton randomize read readjoystick redim rem restore resume return right$ rmdir rnd run "
LBkey$ = LBkey$ +" scan seek select short sin sort space$ spreadsheet sqr statictext step str$ stopmidi struct stylebits sub "
LBkey$ = LBkey$ +" tab tan text textbox textboxcolor$ texteditor texteditorcolor$ text_fs text_nsb text_nsb_ins then time$ "
LBkey$ = LBkey$ +" timer titlebar to trace trim$ txcount ul ulong unloadbmp until upper$ upperleftx upperlefty ur ushort using "
LBkey$ = LBkey$ +" val version$ void wait wend while window windowheight windowwidth window_nf winstring word word$ "
legalchr$ ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_'[].$#"+chr$(34)[setup.main.Window]'-----Begin code for #mainnomainwinWindowWidth=740WindowHeight=150UpperLeftX=int((DisplayWidth-WindowWidth)/2)UpperLeftY=int((DisplayHeight-WindowHeight)/2)'-----Begin GUI objects codecall removespaces
call findfiles ' find all BASs in the directoryTextboxColor$="white"textbox#main.fileisbox,325,15,380,25textbox#main.dotbox,20,60,275,25textbox#main.timebox,325,60,380,25radiobutton#main.NoListing,"No Listing?",[NoListSet],[NoListReset],325,37,100,25radiobutton#main.Listing,"Listing?",[ListSet],[ListReset],460,37,60,25radiobutton#main.Numbers,"With Line Numbers?",[LNSet],[LNReset],580,37,150,25combobox#main.filebox, BASname$(),[selectfile],20,12,275,250'-----End GUI objects codeopen"XRef2 - Liberty BASIC Cross-Index Creation Tool - V2.1 [c] Ken B Smith - June 2011"forwindowas#main
print#main,"font ms_sans_serif 10"print#main,"trapclose [quit.main]"#main.Numbers,"hide"#main.NoListing,"set"[main.inputLoop]'wait here for input eventwait[NoListSet]#main.Numbers,"hide"
Qlisting =0
Qnumbers =0wait[NoListReset]wait[ListSet]#main.Numbers,"show"
Qlisting =1
Qnumbers =0wait[ListReset]wait[LNSet]
Qnumbers =1wait[LNReset]wait[selectfile]'Perform action for the combobox named 'filebox'print#main.filebox,"contents? fileIs$"print#main.filebox,"selectionindex? fileselect"if fileIs$ ="All Files"thencall allfiles
else
BASFile$ = fileIs$
' filesize = val(info$(fileselect,1))' filedate$ = info$(fileselect,2)call start
endifclose#main
end[quit.main]'End the programclose#main
end'---------------------------allfiles--------sub allfiles ' do all files in list in one gofor xx =1to BAScount ' This is the total filecount of "BAS" files
BASFile$ = BASname$(xx)
filesize =val(info$(xx,1))
filedate$ = info$(xx,2)call start
call pause 1000next xx
endsub' --------------------------- start -----------------sub start
redim wordarray$(5000,2)' Flush the word bufferredim stats(10)
longestword =0
BASTxt$ =left$(BASFile$,instr(BASFile$,"."))+"bas"
BASIdx$ =left$(BASFile$,instr(BASFile$,"."))+"idx"
Stimerval =time$("ms")print#main.fileisbox,"Working on - "+ BASFile$
Etimerval =time$("ms")
filetime =(Etimerval - Stimerval)/1000call readascii ' read the txt file to make the idx
Etimerval =time$("ms")
filetime =(Etimerval - Stimerval)/1000call writeidx
print#main.timebox, BASFile$ +" took "+str$(filetime)+" secs or "+str$(int(stats(1)/filetime))+" lines/sec"call pause 2000endsub' ----------------------- writeidx --------------sub writeidx
open BASIdx$ foroutputas#dbf
' add the originating filename and todays date / timeprint#dbf,BASFile$; " X-REF created "; date$(); " "; time$()print#dbf,""print#dbf," DECODE OF Symbology"print#dbf," ---------------------------------"print#dbf," [G] - Variable defined as GLOBAL"print#dbf," [D] - Variable Dimensioned ($)"print#dbf," [d] - Variable or Constant used in Dimension Declaration"print#dbf," [S] - Sub Routine name"print#dbf," [s] - Variable or Constant used in Sub Routine Declaration"print#dbf," [F] & [f] as above, but for Functions"print#dbf,""' now the word list and line data
longestword = longestword +2' establish minimum spacingfor x =1to stats(1)if wordarray$(x,2)<>""then
wordarray$(x,0)="["+ wordarray$(x,2)+"] "+ wordarray$(x,0)else
wordarray$(x,0)=" "+ wordarray$(x,0)endifif wordarray$(x,2)="D"or wordarray$(x,2)="F"then
wordarray$(x,0)= wordarray$(x,0)+"()"endifprint#dbf, wordarray$(x,0);space$(longestword -len(wordarray$(x,0)));wordarray$(x,1)next x
print#dbf,""print#dbf," -------------------------------- "print#dbf,""' Now list out the program for those without line numbersif Qlisting =0goto[endlist]
targetline =0open BASTxt$ forinputas#df ' this is the target ascii filewhileeof(#df)=0lineinput#df, a$ ' take the whole line and find out what it is
targetline = targetline +1if Qnumbers =1thenprint#dbf,str$(targetline);space$(5-len(str$(targetline)));" ";
endifprint#dbf,a$
wendprint#dbf,""print#dbf," -------------------------------- "print#dbf,""close#df
[endlist]close#dbf
endsub' -------------------------- readascii -------------------sub readascii
totalwords =0
maxwordcount =0
maxperline =0
targetline =0
funcdefline =0open BASTxt$ forinputas#df ' this is the target ascii filewhileeof(#df)=0lineinput#df, a$ ' take the whole line and find out what it is
targetline = targetline +1' print #main.dotbox, "Working on line - ";str$(targetline);print#main.dotbox,"Working on line - ";using("#####",targetline)
wordcount =1
metatagword =0
metaid$ =""
funcdefline =0
a$ =trim$(a$)' get the spaces out
rotateflag =1' used to kill quoted textiflen(a$)<2goto[nextline]' nothing there' Now a special case. I have a label in a handler ie #main.gr, "When mouseMove [pixelFollow]"' I need to subvert the rotateflag and allow the quotes and all within to be allowedifinstr(left$(a$,1),"#")>0then rotateflag =2' quotes cancelled for this line' First remove all the punctuation in a line. This is easier than splitting targetword$for y =1tolen(a$)
length =len(a$)
z$ =mid$(a$,y,1)' I need to dump everything between quotes. rotateflag shows beginning and end of quotes as -1 and + 1 respectivelyifasc(z$)=34then
a$ = ADDSPACE$(a$,y)
rotateflag = rotateflag *-1' show quote flag activegoto[nextchr]endifif rotateflag =-1then' quote flag is active ?
a$ = ADDSPACE$(a$,y)goto[nextchr]endifif z$ ="'"then
a$ =left$(a$,y-1)exitfor' lose the rest of the lineendififinstr(legalchr$,z$)=0then' this is not a legal character so ...if y =1then' on the start of a line add a space instead
a$ =" "+mid$(a$,2)goto[nextchr]endifif y = length then' at the end of a line add a space
a$ =left$(a$,length -1)+" "goto[nextchr]endif
a$ = ADDSPACE$(a$,y)' add a space everwhere elseendif[nextchr]next y
' Now we can process a line that only contains words, numbers and keywords
targetword$ ="dummy"' give targetword$ a valuewhile targetword$ <>""
targetword$ =word$(a$,wordcount)
targetword$ =trim$(targetword$)
t$ =" "+lower$(targetword$)+" "' set up a temp string in lowercase to look for keywords' the space either side ensures we don't pick up bits of wordsifinstr(LBkey$,t$)>0then' this is a keyword
t$ =trim$(t$)
funcdefline = targetline ' keyword ID on this lineif t$ ="global"then
metatagword = wordcount +1' the next word to be actioned
metaid$ ="G"' metaid$ = G is a globalendifif t$ ="dim"then
metatagword = wordcount +1
metaid$ ="D"endifif t$ ="sub"then
metatagword = wordcount +1
metaid$ ="S"endifif t$ ="function"then
metatagword = wordcount +1
metaid$ ="F"endifgoto[nextword]' this was a keyword - ignore itendififlen(targetword$)=0goto[nextword]' somehow the word was zero length - so ignore that too.' we have a valid word - file itcall findword
[nextword]
wordcount = wordcount +1wend[nextline]wendclose#df
endsub' -------------------------- find word ------------------------' Find a targetword$ in array wordarray$(x,y) where 0 = word / 1 = lines and make a place for it at wordpos if not theresub findword
wordfound =0
wordplace =0
oldpointer =0
cpointer = stats(1)/2' stats(1) is the total word count to date
cstep = stats(1)/4' half way and increment n/4while cstep >0.25
oldpointer =int(cpointer)if targetword$ = wordarray$(oldpointer,0)thenexitwhile' A hitif targetword$ > wordarray$(oldpointer,0)then
cpointer = cpointer + cstep
else
cpointer = cpointer - cstep
endif
cstep = cstep /2wend
wordplace = oldpointer ' hold that number for a momentif targetword$ = wordarray$(oldpointer,0)then' We have a hit at oldpointer
wordfound = oldpointer ' hold where we found itgoto[makeword]elseif targetword$ = wordarray$(oldpointer +1,0)then' it could be one below
wordfound = oldpointer +1goto[makeword]endifendif' If we get here then the word wasn't found in the existing list
stats(1)= stats(1)+1' stats(1) is total words
wordfound = stats(1)' that is where we are
wordarray$(wordfound,0)= targetword$
hexline$ =str$(targetline)
hexline$ =space$(5-len(hexline$))+ hexline$ ' pad to 5 chrs
wordarray$(wordfound,1)= hexline$
maxwordcount = maxwordcount +1iflen(targetword$)> longestword then longestword =len(targetword$)' print formattinggoto[alldone][makeword]' now add the line number if not already added for this line
hexline$ =str$(targetline)
hexline$ =space$(5-len(hexline$))+ hexline$ ' pad to 5 chrsifinstr(wordarray$(wordfound,1),hexline$)=0then' not there ?
wordarray$(wordfound,1)= wordarray$(wordfound,1)+ hexline$ ' add the hexendif[alldone]' now pick up the status of the metaid$ in wordarray$(wordfound,2)' if the word is on the same line as the definition itself then something must be doneif funcdefline = targetline and metaid$ <>""then' we are on a keyword lineif metatagword = wordcount then' this is the word directly after a keyword = name
wordarray$(wordfound,2)= metaid$ ' give this the capital value if allocatedelseif metaid$ ="G"then
wordarray$(wordfound,2)= metaid$ ' special caseelse
wordarray$(wordfound,2)=lower$(metaid$)' otherwise the lowercaseendifendifendifif wordfound = stats(1)thencall sortme ' new entry - sort itendsub' -------------------- Home Brew sort to get around problems in ordering with LB sort cmd ---------'sort wordarray$(),wordplace,stats(1),0 is what we are replacing' very nasty - but will do for nowsub sortme
[startsort]
sorted =1for sx = stats(1)to2 step -1if wordarray$(sx,0)< wordarray$(sx -1,0)then' and wordarray$(sx - 1,0) <> "" then' swap elements 0 & 1 & 2
temp0$ = wordarray$(sx -1,0)
temp1$ = wordarray$(sx -1,1)
temp2$ = wordarray$(sx -1,2)
wordarray$(sx -1,0)= wordarray$(sx,0)
wordarray$(sx -1,1)= wordarray$(sx,1)
wordarray$(sx -1,2)= wordarray$(sx,2)
wordarray$(sx,0)= temp0$
wordarray$(sx,1)= temp1$
wordarray$(sx,2)= temp2$
sorted =0else
sorted =1exitforendifnext sx
if sorted =0goto[startsort]endsub' ------------------------ findfiles ---------------------sub findfiles
filesDefaultDir$,"*.BAS",info$()
BAScount =val(info$(0,0))for x =0to BAScount
for y =0to2
filedata$(x,y)= info$(x,y)next y
BASname$(x)= info$(x,0)next x
BASname$(0)="All Files"endsub' -----------------------------removespaces ------------------------sub removespaces ' remove spaces from filenames in BASname$() and replace with _filesDefaultDir$,"*.BAS",info$()for x =1toval(info$(0,0))
BASname$(x)= info$(x,0)
newname$ = BASname$(x)
space =instr(newname$," ")while space >0
newname$ =left$(newname$,space-1)+"_"+mid$(newname$,space+1)
space =instr(newname$," ")wendname BASname$(x)as newname$
next x
endsub' ------------------------------ pause -----------------------------------sub pause mil
t=time$("milliseconds")print#main.dotbox," * PAUSE * "whiletime$("milliseconds")<t+mil
wendendsub' ================ Functions =========================function ADDSPACE$(Sa$,Sy)'replace a character from Sa$ at position Sy
ADDSPACE$ =left$(Sa$,Sy-1)+" "+mid$(Sa$,Sy +1)' dump the chr at Syendfunction' The end
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
---------------------------------------- This is the output of itself ----------------------------
xref42.bas X-REF created Jul 10,201120:46:01
DECODE OF Symbology
[G]- Variable defined asGLOBAL[D]- Variable Dimensioned ($)[d]- Variable or Constant used in Dimension Declaration
[S]-Sub Routine name[s]- Variable or Constant used in Sub Routine Declaration
[F] & [f]as above, but for Functions
#dbf 196199200212214215216226228230231232235#df 221222223233247249250345#main 102103104149153#main.dotbox 92253484#main.filebox 99139140#main.fileisbox 91179#main.Listing 95#main.NoListing 94106#main.Numbers 96105110120#main.timebox 93189[alldone]391403[endlist]219234[ListReset]95125[ListSet]95119[LNReset]96133[LNSet]96129[main.inputLoop]107[makeword]372376393[NoListReset]94115[NoListSet]94109[nextchr]274279290295300[nextline]260343[nextword]330333339[quit.main]152[selectfile]99137[setup.main.Window]75[startsort]42644601111121221742052072102122192202222412422432442452492552572642873103333513523533593613703743843994294314344374404464564574584614634704714740.253571121130160162189203212224225251254259264267269273277283288294314318322326340354355374375382383388389399400419427428429431432433434435436438442470475491[d]1032173100941000165182187129915911508196[d]22530828316317220220420520926026428935436640941241442843343643945820929920001902591929394959625099275929932591939434732713794959638091934355[d]402426460955226386397[d]500030172580966092939574080[F] ADDSPACE$()272278298490491
a$ 223228250258260264267268269272278283289294298306[S] allfiles 142158[G] BAScount 44160456457[G] BASFile$ 44144161176177179189199[G] BASIdx$ 44177196[D] BASname$()2799161461463471472478[G] BASTxt$ 44176221247
cpointer 354358362364
cstep 355357362364366[G] Etimerval 43181182186187[D] filedata$()25459[G] filedate$ 46163[G] fileIs$ 41141144[G] filesize 45162
filetime 182187189[S] findfiles 88453[S] findword 337350[G] funcdefline 54245257312406
hexline$ 385386388396397399400
hide 105110[D] info$()26162163455456459461469470471[G] LBkey$ 48585960616263646566676869707172310[G] legalchr$ 4973287
length 268293294[G] longestword 51174202212390[d] maxinput 23242527[G] maxperline 3738243[G] maxwordcount 36242389[G] metaid$ 53256315319323327406409411412414[G] metatagword 52255314318322326408[s] mil 482485
newname$ 472473475476478
oldpointer 353358359361369370371374375[S] pause 165190482[G] Qlisting 55111121219[G] Qnumbers 56112122130225[S] readascii 184240[S] removespaces 87467
rotateflag 259264273277[f] Sa$ 490491[G] Stimerval 42178182187[f] Sy 490491
set 106
show 120
sorted 427440442446[S] sortme 419425
space 473474475476[S] start 147164171[D] stats()32173189203354355382383419428
sx 428429431432433434435436437438439445
t 483485[G] t$ 47308310311313317321325[G] targetline 40220224226244251253312385396406[G] targetword$ 39304305306307308333359361370374384390
temp0$ 431437
temp1$ 432438
temp2$ 433439[G] totalwords 37241[D] wordarray$()30172204205207209210212359361370374384388399400409412414429431432433434435436437438439[G] wordcount 35254306314318322326340408[G] wordfound 34351371375383384388399400409412414419[G] wordplace 50352369[S] writeidx 188194
x 203204205207209210212213457459461462470471472478479
xx 160161162163166
y 267269272278283288293298301458459460
z$ 269271282287