parms=askline("Sorting - all parms alterable","startcol, # of cols to sort, max linelength, a | d for ascending or descending","1 20 255 a") ;
parsedata(parms) ; see what we've got
if param0<>4 then continue ; invalid # of parms
if !isint(param3) | param3<1 then continue ; check valid maxsize
else lmax=param3 ; store lmax value
if !(strlower(param4)=="a" | strlower(param4)=="d") then continue ; must be asc or des
if strlower(param4)=="a" then sorting=1 ; set sort order
else sorting=0 ; desc
if !isint(param1) | param1<1 then continue ; check for valid start col
scol=param1 ; set starting column
if !isint(param2) | param2<1 then continue ; check valid # of cols to sort
numcols=param2 ; set # of cols to sort on
if param1>lmax then continue ; start of sort after max?
if param1+param2>param3 then continue ; ensure reasonableness
break ; user got input data right
endwhile ;
started=timeymdhms() ; get accurate elapsed time
lmax2=lmax+2 ; max line length + @crlf
if wgetselstate() then ; anything selected
xxcurl2=wgetlineno() ; get end of selection line number
wcut() ; yes, copy it to clipboard
xxcurl1=wgetlineno() ; get start of selection line number
else ;
xxcurl1=1 ; line # 1 for all
wSelectAll() ; no, get the lot
xxcurl2=wgetlineno() ; get end of selection line number
wcut() ; now
endif ;
if (xxcurl2-xxcurl1+1)==1 then maxfix=2000000 ; can't determine if 1 line or bottom up selection was done, be safe
else maxfix=0 ; normal
afiles=(xxcurl2-xxcurl1+1)*(lmax2)+maxfix ; get size of selection
rbuf=binaryalloc(afiles) ; buf for current file
binaryclipget(rBuf, 1) ; and stick it in the buffer
Brk = binaryeodget(rBuf) ; max buffer
xbuf=binaryalloc(brk+1) ; get proper buffer
binarycopy(xbuf,0,rbuf,0,brk) ; copy good data
binaryfree(rbuf) ; dealloc orig buffer
rbuf=xbuf ; end of shuffle
cbuf=binaryalloc(brk+1) ; buf in case of cancel
binaryclipget(cBuf, 1) ; and stick it in recovery buffer
wbuf=0 ; show no buffer yet for sorted recs
if brk<3 then goto gohome ; shame on you - try to sort 1 record!!!!!
totalbar=binarystrcnt(rbuf,0,brk,@crlf) ; find # of @crlf=line length + ?
if binaryindexex(rbuf,brk-2,@crlf,@fwdscan,0)<0 then totalbar=totalbar+1 ; last rec no @crlf
if totalbar==1 then goto gohome ; shame on you - try to sort 1 record!!!!!
wbuf=binaryalloc(totalbar*lmax2) ; buf for sorted records, very efficient!
ls=0 ; starting point for unsorted line 1
ose=0 ; offset for o/p buffer
rc=1 ; standard rec with @crlf
while ls < Brk ; go through input buffer
ll = binaryindexex(rbuf,ls,@crlf,@fwdscan,0)-ls ; ll is length of current line - @crlf
if ll < 0 ; if @crlf not found
ll=brk-ls ; end of buffer;remaining data.
rc=0 ; @crlf required
endif ;
if ll > lmax ; max line exceeded
badline=binarypeekstr(rbuf,ls,min(lmax,ll)) ; get bad line
binaryclipput(cBuf, 1) ; restore screen to before sort
wpaste() ; stick back in edit file
wgotoline(xxcurl1) ; point back at original location
binaryfree(rBuf) ; housekeeping
binaryfree(wBuf) ; housekeeping
binaryfree(cBuf) ; housekeeping
message("Line length exceeded - Sort aborted",badline) ; tell user the bad news
exit ; exit
endif ;
if rc ; if trailing @crlf
binarycopy(wBuf,ose, rBuf, ls, ll+2) ; copy data + @crlf into wbuf
else ;
binarycopy(wBuf, ose, rBuf, ls, ll) ; copy data only, no @crlf
binarypokestr(wbuf,binaryeodget(wbuf),@crlf) ; add missing @crlf, should be last rec
endif ;
ls=ls+ll+2 ; add length of old data + @crlf
ose=ose+lmax2 ; incr o/p buffer offset
tsf=tsf+1 ; records processed
if !(tsf mod 20) then wStatusMsg(strcat(tsf/2,"/",totalbar," lines, window locked for processing - all data in clipboard. Problems?-press Ctrl+V to restore screen.")) ;
endwhile ;
Brk=ose ; get max used
binaryeodset(wbuf,ose) ; set eod
if sorting then binarysort(wbuf,lmax2,scol-1,numcols,@string|@ascending) ; sort lines in asc
else binarysort(wbuf,lmax2,scol-1,numcols,@string|@descending) ; sort in desc
orc=rc ; save last yes/no @crlf indicator
ls=binaryindex(wbuf,0,"",@fwdscan) ; skip over nulls in asc sort, 0 in des
brk=brk+ls ; establish end of sorted records
ose=0 ; offset for i/p buffer
while ls < Brk ; go through input buffer, now fixed lmax2 length
xxx=binaryindexnc(wbuf,ose+lmax2-1,"",@backscan) ; find first non null, should be @crlf
ose=xxx+1 ; next line on screen - data,@crlf,data...
ls=ls+lmax2 ; input buffer's new offset
tsf=tsf+1 ; records processed
if !(tsf mod 20) then wStatusMsg(strcat(tsf/2,"/",totalbar," lines, window locked for processing - all data in clipboard. Problems?-press Ctrl+V to restore screen.")) ;
endwhile ;
if orc then binaryeodset(wbuf,ose) ; set eod last rec had a @crlf
else binaryeodset(wbuf,ose-2) ; this one did not
binaryclipput(wBuf, 1) ; text format
:gohome ;
wpaste() ; stick back in edit file
wgotoline(xxcurl1) ; point back at original location