OpenVMS Source Code Demos
SORT_DEMO.BAS
1000 %title "sort_demo_100.bas"
%ident "version_100.1"
!========================================================================================================================
! title : sort_demo_100.bas
! author : Neil Rieck (https://neilrieck.net/)
! history:
! ver who when what
! --- --- ------ --------------------------------------------------------------------------------------------------------
! 100 NSR 050104 1. original code
!========================================================================================================================
! Sample File Name: NEIL_SAMPLE.TXT
! Contents: ABCDZ
! ABCDA
! ABCDA <--- this key is a duplicate
! ABCDB
! ABCDX
! ABCDD
! ABCDE
! Offset Info: 0123456789012345678901234567890
!========================================================================================================================
option type=explicit ! cuz tricks are for kids
!
! <<< system declarations >>>
!
%include "$sordef" %from %library "sys$library:basic$starlet" ! sor$
%include "sor$routines" %from %library "sys$library:basic$starlet" ! sor$
%include "$dscdef" %from %library "sys$library:basic$starlet" ! dsc$
%include "$fabdef" %from %library "sys$library:basic$starlet" ! fab$
!
! <<< home-brewed functions >>>
!
external long function fn_sort_eq%(string by ref, string by ref, word by ref, word by ref, long by ref)
!
! <<< variable declarations >>>
!
declare word lrl% , ! &
long srttype% , ! sort type &
addr_sort_eq% , ! address of function sort_eq &
status% , ! status &
context% ! SOR$ context (zap before setup of any new SOR$)
!
! <<< key descriptor record >>>
!
record my_key_dsc !
word my_data_type !
word my_order !
word my_offset !
word my_length !
end record !
!
! key list record
!
record key_rec !
word num_keys !
my_key_dsc my_key(9) ! reserve space for 10 key descriptors (0-9)
end record !
!
declare key_rec key_buffer ! declare our variable
!
! <<< init >>>
!
key_buffer::num_keys = 1 ! we will only use one key for this demo
!
key_buffer::my_key(0)::my_data_type = DSC$K_DTYPE_T !
key_buffer::my_key(0)::my_order = 0 !
key_buffer::my_key(0)::my_offset = 0 !
key_buffer::my_key(0)::my_length = 5 !
!
! key_buffer::my_key(1)::my_data_type = DSC$K_DTYPE_T x could be used for another key
! key_buffer::my_key(1)::my_order = 0 x
! key_buffer::my_key(1)::my_offset = 5 x
! key_buffer::my_key(1)::my_length = 2 x
!
! key_buffer::my_key(2)::my_data_type = DSC$K_DTYPE_T x could be used for another key
! key_buffer::my_key(2)::my_order = 0 x
! key_buffer::my_key(2)::my_offset = 7 x
! key_buffer::my_key(2)::my_length = 3 x
!
addr_sort_eq% = LOC(FN_SORT_EQ%) ! get addr of function
context% = 0 ! always init context before first call to SOR$
!----------------------------------------------------------------------------------------------------
! SOR$PASS_FILES [inp_desc] [,out_desc] [,org] [,rfm] [,bks] [,bls] [,mrs] [,alq] [,fop] [,fsz] [,context]
! source: CD-ROM
!
status% = SOR$PASS_FILES ("neil_sample.txt", "neil_sample_out.txt",,,,,,,,,context% )
print "-i- status: "+ str$(status%)
!----------------------------------------------------------------------------------------------------
! SOR$BEGIN_SORT [key_buffer] [,lrl] [,options] [,file_alloc] [,user_compare] [,user_equal] [,sort_process]
! [,work_files] [,context]
! source: CD-ROM
!
! EXTERNAL LONG FUNCTION SOR$BEGIN_SORT( OPTIONAL ANY BY REF, WORD BY REF, LONG BY REF, LONG BY REF, &
! LONG BY VALUE, LONG BY VALUE, BYTE BY REF, BYTE BY REF, LONG BY REF )
! source: extracted from file: SYS$LIBRARY:STARLETBASIC$STARLET.TLB
!
%let %method=1% ! 0=basic (no call to function), 1=advanced
%if %method=0% %then !
STATUS% = SOR$BEGIN_SORT(key_buffer::num_keys,LRL%,,,,,,,context%) !
%else !
STATUS% = SOR$BEGIN_SORT(key_buffer::num_keys,LRL%,,,,addr_sort_eq%,,,context%)
%end %if !
print "-i- status: "+ str$(status%) !
!----------------------------------------------------------------------------------------------------
status% = SOR$SORT_MERGE(context%) !
print "-i- status: "+ str$(status%) !
!----------------------------------------------------------------------------------------------------
status% = SOR$END_SORT(context%) !
print "-i- status: "+ str$(status%) !
30000 end !
!========================================================================================================================
!
! <<< external functions >>>
!
!----------------------------------------------------------------------------------------------------
! title: fn_sort_eq
! purpose: come here when SOR$ has discovered a duplicate key
!----------------------------------------------------------------------------------------------------
31000 function long fn_sort_eq% (string rec_1 by ref, string rec_2 by ref, &
word len_1 by ref, word len_2 by ref, long ctx)
option type=explicit ! cuz tricks are for kids
!
%include "$sordef" %from %library "sys$library:basic$starlet" ! sor$
!
print "-i- in function 'fn_sort_eq' (deleting duplicate record)" !
!
! implementation note:
! if we only call SOR$ above with one key and no other data, we will only hit this routine when
! rec_1 = rec_2 so the next test will be superfluous, However, if the data line was longer then
! this routine could be used to test other non-key data.
!
if seg$(rec_1, 1%, 5%) < seg$(rec_2, 1%, 5%) !
then
fn_sort_eq% = SOR$_DELETE1
else
fn_sort_eq% = SOR$_DELETE2
end if
end function
!
Back to
Home
Neil Rieck
Waterloo, Ontario, Canada.