midrange.com code scratchpad
Name:
CP1552R - sort compile-time array
Scriptlanguage:
Plain Text
Tabwidth:
4
Date:
10/03/2018 02:42:25 pm
IP:
Logged
Description:
The purpose of this program is to sort source files. Specifically, to sort compile time arrays (so that
%LookUp will can a binary search). Enter QS over the line number at the start and end of the lines to be
sorted. This program can either be specified in the registry or by user (using option 13 - Change session
defaults). This is an example. In real life, I don't use arrays because RPG won't let me define their length
at run time. For this example I am assuming a compile time array will never be larger than 512. Any number
up to a million will work, and, considering that source files have limits (~32k records) this program really
doesn't need a dynamically defined array.
Code:
  1.       //--------------------------------------------------------------------------------------------------------------//
  2.       //                                                                                                              //
  3.       //                                                                                                              //
  4.       //                           CP1552R - QIBM_QSU_LCMD (SEU user defined) exit program                            //
  5.       //                                                 sort records                                                 //
  6.       //                                                                                                              //
  7.       //                                                                                                              //
  8.       //--------------------------------------------------------------------------------------------------------------//
  9.        Ctl-Opt dftActGrp(*No) actGrp(*Caller)
  10.                debug(*Yes) option(*SrcStmt:*NoDebugIO:*NoUnRef)
  11.                Main(cp1552r)                                                   ;
  12.       //--------------------------------------------------------------------------------------------------------------//
  13.       //                                                                                                              //
  14.       //... procedure interfaces ...                                                                                  //
  15.       //                                                                                                              //
  16.       //--------------------------------------------------------------------------------------------------------------//
  17.       //
  18.       // ... services (external) ...
  19.       //
  20.        Dcl-PR memcpy                        ExtProc('memcpy')                  ;
  21.          *n                 Pointer         Value                              ;
  22.          *n                 Pointer         Value                              ;
  23.          *n                 Uns(10)         Value                              ;
  24.        End-PR                                                                  ;
  25.  
  26.        Dcl-PR memcmp        Int(10)         ExtProc('memcmp')                  ;
  27.          *n                 Pointer         Value                              ;
  28.          *n                 Pointer         Value                              ;
  29.          *n                 Uns(10)         Value                              ;
  30.        End-PR                                                                  ;
  31.  
  32.        Dcl-PR qsort                         ExtProc('qsort')                   ;
  33.          *n                 Pointer         Value                              ;
  34.          *n                 Uns(10)         Value                              ;
  35.          *n                 Uns(10)         Value                              ;
  36.          *n                 Pointer(*Proc)  Value                              ;
  37.        End-PR                                                                  ;
  38.       //--------------------------------------------------------------------------------------------------------------//
  39.       //                                                                                                              //
  40.       // ... global variables/constants ...                                                                           //
  41.       //                                                                                                              //
  42.       //--------------------------------------------------------------------------------------------------------------//
  43.        Dcl-DS input         Qualified                       Based(input@)      ;
  44.          recLen             Int(10)                                            ;
  45.          csrRrn             Int(10)                                            ;
  46.          csrPos             Int(10)                                            ;
  47.          ccsid              Int(10)                                            ;
  48.          recCnt             Int(10)                                            ;
  49.          member             Char(10)                                           ;
  50.          file               Char(10)                                           ;
  51.          library            Char(10)                                           ;
  52.          mbrTyp             Char(10)                                           ;
  53.          fkey               Char(1)                                            ;
  54.          mode               Char(1)                                            ;
  55.          spltSession        Char(1)                                            ;
  56.          rsvr01             Char(1)                                            ;
  57.        End-DS                                                                  ;
  58.        Dcl-DS output        Qualified                       Based(output@)     ;
  59.          rtnCode            Char(1)                                            ;
  60.          rsrv01             Char(3)                                            ;
  61.          recCnt             Int(10)                                            ;
  62.          srcSeqA            Char(1)                                            ;
  63.          srcSeq             Char(6)                                            ;
  64.          rsrv002            Char(22)                                           ;
  65.        End-DS                                                                  ;
  66.        Dcl-DS txtDta        Qualified                       Based(txtDet@)     ;
  67.          command            Char(7)                                            ;
  68.          rtnCode            Ind                                                ;
  69.          srcSeq             Char(6)                                            ;
  70.          srcDat             Char(6)                                            ;
  71.          srcDta             Char(1)                                            ;// only need address
  72.        End-DS                                                                  ;
  73.        Dcl-DS srcDta        LikeDS(txtDta)                  Based(srcDta@)     ;
  74.  
  75.        Dcl-S  szSrcDta      Int(5)                                             ;
  76.        Dcl-S  szTxtDta      Int(5)                                             ;
  77.        Dcl-S  $I            Int(5)                                             ;
  78.        Dcl-S  @srcDta       Pointer         Dim(512)                           ;// dimension hard-coded for example
  79.        Dcl-S  txtHdr@       Pointer                                            ;
  80.  
  81.        Dcl-C  #QSORTCOMP    %PAddr('QSORTCOMP')                                ;
  82.        Dcl-C  #POINTERSIZE  %Size(txtHdr@)                                     ;// in case pointerSize ever changes
  83.        Dcl-C  #SRCDTA@      %Addr(@srcDta)                                     ;
  84.        Dcl-C  #QS           'QS     '                                          ;
  85.       //--------------------------------------------------------------------------------------------------------------//
  86.       //                                                                                                              //
  87.       //                                                  Procedures                                                  //
  88.       //                                                                                                              //
  89.       //--------------------------------------------------------------------------------------------------------------//
  90.       //                                                   Mainline                                                   //
  91.       //--------------------------------------------------------------------------------------------------------------//
  92.        Dcl-Proc cp1552r                                                        ;
  93.        Dcl-PI *n                                            ExtPgm             ;
  94.          pm1@               Pointer                                            ;// sure would be nice to have
  95.          pm2@               Pointer                                            ;// a GLOBAL keyword, and force
  96.          pm3@               Pointer                                            ;// global scope on our arguments
  97.        End-PI                                                                  ;
  98.        input@  = pm1@                                                          ;
  99.        output@ = pm2@                                                          ;
  100.        txtHdr@ = pm3@                                                          ;
  101.        init()                                                                  ;
  102.        load()                                                                  ;
  103.        prcssFncKey()                                                           ;
  104.        prcssCommand()                                                          ;
  105.        unload()                                                                ;
  106.        eoj()                                                                   ;
  107.        Return                                                                  ;
  108.        End-Proc                                                                ;
  109.       //--------------------------------------------------------------------------------------------------------------//
  110.        Dcl-Proc load                                                           ;
  111.        txtDet@ = txtHdr@                                                       ;
  112.        For $I = 1 to input.recCnt                                              ;
  113.           @srcDta($I)    = %Alloc(szSrcDta)                                    ;
  114.           srcDta@        = @srcDta($I)                                         ;
  115.           srcDta.command = txtDta.command                                      ;
  116.           srcDta.srcSeq  = txtDta.srcSeq                                       ;
  117.           srcDta.srcDat  = txtDta.srcDat                                       ;
  118.           srcDta.rtnCode = *Off                                                ;
  119.           memcpy( %Addr(srcDta.srcDta)
  120.                 : %Addr(txtDta.srcDta)
  121.                 : input.reclen
  122.                 )                                                              ;
  123.           txtDet@ += szTxtDta                                                  ;
  124.        EndFor                                                                  ;
  125.        Return                                                                  ;
  126.        End-Proc                                                                ;
  127.       //--------------------------------------------------------------------------------------------------------------//
  128.        Dcl-Proc prcssFncKey                                                    ;
  129.        End-Proc                                                                ;
  130.       //--------------------------------------------------------------------------------------------------------------//
  131.        Dcl-Proc prcssCommand                                                   ;
  132.  
  133.        Dcl-S tstCmd1        Like(txtDta.command)                               ;
  134.        Dcl-S tstCmd2        Like(txtDta.command)                               ;
  135.  
  136.        // right now, we are only interested in processing user defined
  137.        // command QS - if it doesn't contain a QS in the first record and
  138.        // the next to last, we are going to return an error
  139.  
  140.        srcDta@ = @srcDta(1)                                                    ;
  141.        tstCmd1 = srcDta.command                                                ;
  142.        srcDta@ = @srcDta(input.recCnt-1)                                       ;
  143.        tstCmd2 = srcDta.command                                                ;
  144.        If ( tstCmd1 = #QS And tstCmd2 = #QS And input.recCnt > 2 )             ;
  145.  
  146.          qsort( #SRCDTA@                                                          // I like sorting arrays of pointers
  147.               : input.recCnt - 1
  148.               : #POINTERSIZE
  149.               : #QSORTCOMP
  150.               )                                                                ;
  151.  
  152.          txtDet@ = txtHdr@                                                     ;
  153.          For $I = 1 to input.recCnt - 1                                        ;
  154.             srcDta@        = @srcDta($I)                                       ;
  155.             txtDta.srcSeq  = srcDta.srcSeq                                     ;
  156.             txtDta.srcSeq  = srcDta.srcSeq                                     ;
  157.             txtDta.srcDat  = srcDta.srcDat                                     ;
  158.             txtDta.rtnCode = *Off                                              ;
  159.             txtDta.command = *Blanks                                           ;
  160.             memcpy( %Addr(txtDta.srcDta)
  161.                   : %Addr(srcDta.srcDta)
  162.                   : input.reclen
  163.                   )                                                            ;
  164.             txtDet@  += szTxtDta                                               ;
  165.          EndFor                                                                ;
  166.          output.rtnCode = '0'                                                  ;
  167.          output.recCnt  = input.recCnt - 1                                     ;
  168.          output.srcSeq  = '000000'                                             ;
  169.          output.srcSeqA = '0'                                                  ;
  170.        Else                                                                    ;// error
  171.          output.rtnCode = '1'                                                  ;
  172.          output.recCnt  = 0                                                    ;
  173.          output.srcSeq  = '000000'                                             ;
  174.          output.srcSeqA = *Blank                                               ;
  175.        EndIf                                                                   ;
  176.        Return                                                                  ;
  177.        End-Proc                                                                ;
  178.       //--------------------------------------------------------------------------------------------------------------//
  179.        Dcl-Proc unload                                                         ;
  180.  
  181.        txtDet@ = txtHdr@                                                       ;
  182.        For $I = 1 to input.recCnt                                              ;
  183.           DeAlloc @srcDta($I)                                                  ;
  184.           txtDet@ += szTxtDta                                                  ;
  185.        EndFor                                                                  ;
  186.  
  187.        Return                                                                  ;
  188.        End-Proc                                                                ;
  189.       //--------------------------------------------------------------------------------------------------------------//
  190.        Dcl-Proc qsortComp                                                      ;
  191.        Dcl-PI *n            Int(10)                                            ;// We're not supposed to have favorites,
  192.          ds1@@              Pointer         Value                              ;// but I think this is my favorite
  193.          ds2@@              Pointer         Value                              ;// subroutine - getting an awful lot
  194.        End-PI                                                                  ;// done with very little code
  195.        Dcl-S  ds1@          Pointer                         Based(ds1@@)       ;
  196.        Dcl-S  ds2@          Pointer                         Based(ds2@@)       ;
  197.        Dcl-DS ds1           LikeDS(srcDta)                  Based(ds1@)        ;
  198.        Dcl-DS ds2           LikeDS(srcDta)                  Based(ds2@)        ;
  199.  
  200.        Return memcmp( %Addr(ds1.srcDta)
  201.                     : %Addr(ds2.srcDta)
  202.                     : szSrcDta
  203.                     )                                                          ;
  204.  
  205.        End-Proc                                                                ;
  206.       //--------------------------------------------------------------------------------------------------------------//
  207.        Dcl-Proc init                                                           ;
  208.        szSrcDta = %Len(srcDta) + input.recLen - 1                              ;
  209.        szTxtDta = %Len(txtDta) + input.reclen - 1                              ;
  210.        Return                                                                  ;
  211.        End-Proc                                                                ;
  212.       //--------------------------------------------------------------------------------------------------------------//
  213.        Dcl-Proc eoj                                                            ;
  214.        Return                                                                  ;
  215.        End-Proc                                                                ;
  216.       //--------------------------------------------------------------------------------------------------------------//
  217.  
© 2004-2019 by midrange.com generated in 0.009s valid xhtml & css