home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_49.arc / GENSORT.ARC / GENSRT.M2 < prev   
Text File  |  1989-07-11  |  10KB  |  323 lines

  1. (* Micro Cornucopia Magazine Issue #49
  2.    Units and Modules Figure 1 - Generic sort routines *)
  3.  
  4. unit GenSort;
  5.  
  6. (*
  7.   Author: Michael S. Hunt    Date: June 1, 1989
  8.   This source code is release into the public domain.
  9. *)
  10.  
  11. interface
  12.  
  13. const MAX_KEYS = 16;
  14.       MAX_SRTS = 8;
  15.       MAX_MSG = 10;
  16.       MAX_DATA_LEN = 32768;
  17.       MSG_SIZE = 40;
  18.       srtMsg : array[1..MAX_MSG] of string[MSG_SIZE] =
  19.                    ('successful operation',
  20.                     'zero records left to retrieve ',
  21.                     'routines called in incorrect order',
  22.                     'maximum sorts exceeded',
  23.                     'too many keys',
  24.                     'invalid sort id',
  25.                     'not valid sort',
  26.                     'sort in release state',
  27.                     'sort in retrieve state',
  28.                     'sort done');
  29.       GenSrtErr_NM   =  0;   (* successful operation *)
  30.       GenSrtErr_ZR   =  1;   (* zero records left to retrieve *)
  31.       GenSrtErr_ICO  =  2;   (* routines called in incorrect order *)
  32.       GenSrtErr_MSE  =  3;   (* maximum sorts exceeded *)
  33.       GenSrtErr_TMK  =  4;   (* too many keys *)
  34.       GenSrtErr_ISI  =  5;   (* invalid sort id *)
  35.       GenSrtSt_NV    =  6;   (* not valid sort *)
  36.       GenSrtSt_REL   =  7;   (* sort in release state *)
  37.       GenSrtSt_RET   =  8;   (* sort in retrieve state *)
  38.       GenSrtSt_DONE  =  9;   (* sort done *)
  39.       GenSrtDType_BL =  1;   (* type boolean *)
  40.       GenSrtDType_B  =  2;   (* type byte *)
  41.       GenSrtDType_W  =  3;   (* type word *)
  42.       GenSrtDType_C  =  4;   (* type char 1 byte *)
  43.       GenSrtDType_ST =  5;   (* type string 1..255 bytes *)
  44.       GenSrtOrder_A  =  0;   (* ascending sort order *)
  45.       GenSrtOrder_D  =  1;   (* descending sort order *)
  46.  
  47. type  KeyRec = record
  48.                    dataType, order, offset, length : word
  49.                end;
  50.       Keyarr = array[1..MAX_KEYS*4+1] of word;
  51.       Bytes  = array[1..MAX_DATA_LEN] of byte;
  52.       Chars  = array[1..MAX_DATA_LEN] of char;
  53.       PtrRec = record
  54.                  ofs, seg : word
  55.                end;
  56.       SrtKeyRec = record
  57.                        nbrKeys : word;
  58.                        key : array[1..MAX_KEYS] of KeyRec
  59.                    end;
  60.       SrtStatRec = record
  61.                         nbrKeys, dataLen, keyLen, srtState : word;
  62.                         nbrRec  : longint
  63.                     end;
  64.       SrtStr = string[80];
  65.  
  66. var   srtKeyArr  : array[1..MAX_SRTS] of SrtKeyRec;
  67.       srtStatArr : array[1..MAX_SRTS] of SrtStatRec;
  68.  
  69. procedure GenSrtBegin (var key; dataLen : word; var srtId : word;
  70.                       var srtStatus : word);
  71.  
  72. function GenSrtBeginF (var key; dataLen : word; var srtId : word) : word;
  73.  
  74. procedure GenSrtRelease (var rec; srtId : word; var srtStatus : word);
  75.  
  76. function GenSrtReleaseF (var rec; srtId : word) : word;
  77.  
  78. procedure GenSrtDoSrt (srtId : word; var srtStatus :word);
  79.  
  80. function GenSrtDoSrtF (srtId : word) : word;
  81.  
  82. procedure GenSrtRetrieve (var rec; srtId : word; var srtStatus : word);
  83.  
  84. function GenSrtRetrieveF (var rec; srtId : word) : word;
  85.  
  86. procedure GenSrtEnd (srtId : word; var srtStatus : word);
  87.  
  88. function GenSrtEndF (srtId : word) : word;
  89.  
  90. procedure GenSrtStat (var srtStatus : SrtStatRec; srtId :word);
  91.  
  92. procedure GenSrtMsg (srtStatus : word; var srtString : SrtStr);
  93.  
  94. implementation
  95.  
  96. uses GenBinTree;
  97.  
  98. var srtRootArr : array[1..MAX_SRTS] of treePtr;
  99.     j : word;
  100.  
  101. function NextSrtId : word;
  102. var  j : word;
  103.      done : boolean;
  104. begin
  105.   j := 1;
  106.   NextSrtId := 0;
  107.   done := false;
  108.   repeat
  109.     if srtStatArr[j].srtState = GenSrtSt_NV then
  110.     begin
  111.       NextSrtId := j;
  112.       done := true;
  113.       srtStatArr[j].srtState := GenSrtSt_REL
  114.     end;
  115.     j := j+1
  116.   until (j > MAX_SRTS) OR (done)
  117. end;
  118.  
  119. function ValidSrtId(srtId : word) : boolean;
  120. begin
  121.   if (srtId <= MAX_SRTS) AND (srtId > 0) then
  122.     if srtStatArr[srtId].srtState <> GenSrtSt_NV then
  123.       ValidSrtId := true
  124.     else
  125.       ValidSrtId := false
  126. end;
  127.  
  128. procedure ClearSrtId(srtId : word);
  129. begin
  130.   if (srtId <= MAX_SRTS) AND (srtId > 0) then
  131.     srtStatArr[srtId].srtState := GenSrtSt_NV
  132. end;
  133.  
  134. procedure Descend(var rec; recLen : word);
  135. var j : word;
  136. begin
  137.   for j := 1 to recLen do
  138.   begin
  139.     Bytes(rec)[j] := $FF xor Bytes(rec)[j]
  140.   end
  141. end;
  142.  
  143. procedure GenSrtBegin (var key; dataLen : word; var srtId : word;
  144.                       var srtStatus : word);
  145. begin
  146.     srtStatus := GenSrtBeginF(key, dataLen, srtID)
  147. end;
  148.  
  149. function GenSrtBeginF (var key; dataLen : word; var srtId : word) : word;
  150. var j, k : word;
  151. begin
  152.      srtId := NextSrtId;
  153.      if srtId > 0 THEN
  154.      begin
  155.         srtKeyArr[srtId].nbrkeys := KeyArr(key)[1];
  156.         if srtKeyArr[srtId].nbrkeys <= MAX_KEYS then
  157.         begin
  158.              for j := 1 to srtKeyArr[srtId].nbrKeys do
  159.              begin
  160.                  srtKeyArr[srtId].key[j].dataType := KeyArr(key)[j*4-2];
  161.                  srtKeyArr[srtId].key[j].order := KeyArr(key)[j*4-1];
  162.                  srtKeyArr[srtId].key[j].offset := KeyArr(key)[j*4];
  163.                  srtKeyArr[srtId].key[j].length := KeyArr(key)[j*4+1]
  164.              end;
  165.              srtStatArr[srtId].nbrKeys := srtKeyArr[srtId].nbrKeys;
  166.              srtStatArr[srtId].dataLen := dataLen;
  167.              srtStatArr[srtId].keyLen := 0;
  168.              for j := 1 to srtKeyArr[srtId].nbrKeys do
  169.                srtStatArr[srtId].keyLen := srtStatArr[srtId].keyLen
  170.                                         +  srtKeyArr[srtId].key[j].length;
  171.              srtStatArr[srtId].nbrRec := 0;
  172.              srtStatArr[srtId].srtState := GenSrtSt_REL;
  173.              GenSrtBeginF := GenSrtErr_NM
  174.         end
  175.         else
  176.         begin
  177.             ClearSrtId(srtId);
  178.             GenSrtBeginF := GenSrtErr_TMK
  179.         end
  180.      end
  181.      else
  182.          GenSrtBeginF := GenSrtErr_MSE
  183. end;
  184.  
  185. procedure GenSrtRelease (var rec; srtId : word; var srtStatus : word);
  186. begin
  187.     srtStatus := GenSrtReleaseF(rec, srtId)
  188. end;
  189.  
  190. function GenSrtReleaseF (var rec; srtId : word) : word;
  191. var data, key, tkey : dataPtr;
  192.     j, k : word;
  193. begin
  194.   if ValidSrtId(srtId) then
  195.   begin
  196.     k := 1;
  197.     GetMem(key, srtStatArr[srtId].keyLen);
  198.     GetMem(data, srtStatArr[srtId].dataLen);
  199.     tkey := key;
  200.     for j := 1 to srtKeyArr[srtId].nbrKeys do
  201.     begin
  202.       if (srtKeyArr[srtId].key[j].dataType = GenSrtDType_BL) then
  203.       begin
  204.         tkey^ := Chars(rec)[srtKeyArr[srtId].key[j].offset];
  205.         Inc(PtrRec(tkey).ofs,1)
  206.       end
  207.       else if (srtKeyArr[srtId].key[j].dataType = GenSrtDType_B) then
  208.       begin
  209.         tkey^ := Chars(rec)[srtKeyArr[srtId].key[j].offset];
  210.         Inc(PtrRec(tkey).ofs,1)
  211.       end
  212.       else if (srtKeyArr[srtId].key[j].dataType = GenSrtDType_W) then
  213.       begin
  214.         tkey^ := Chars(rec)[srtKeyArr[srtId].key[j].offset+1];
  215.         Inc(PtrRec(tkey).ofs,1);
  216.         tkey^ := Chars(rec)[srtKeyArr[srtId].key[j].offset];
  217.         Inc(PtrRec(tkey).ofs,1)
  218.       end
  219.       else if (srtKeyArr[srtId].key[j].dataType = GenSrtDType_C) then
  220.       begin
  221.         tkey^ := Chars(rec)[srtKeyArr[srtId].key[j].offset];
  222.         Inc(PtrRec(tkey).ofs,1)
  223.       end
  224.       else if (srtKeyArr[srtId].key[j].dataType = GenSrtDType_ST) then
  225.       begin
  226.         for k := 1 to srtKeyArr[srtId].key[j].length do
  227.         begin
  228.           tkey^ := Chars(rec)[srtKeyArr[srtId].key[j].offset+k];
  229.           Inc(PtrRec(tkey).ofs,1)
  230.         end
  231.       end;
  232.       if (srtKeyArr[srtId].key[j].order <> GenSrtOrder_A) then
  233.       begin
  234.         Descend(key^, srtKeyArr[srtId].key[j].length)
  235.       end
  236.     end;
  237.     Move(rec, data^, srtStatArr[srtId].dataLen);
  238.     GenBinInsert (srtRootArr[srtId], key, srtStatArr[srtId].keyLen,
  239.                data, srtStatArr[srtId].dataLen);
  240.     srtStatArr[srtId].nbrRec := srtStatArr[srtId].nbrRec + 1;
  241.   end
  242.   else
  243.     GenSrtReleaseF := GenSrtErr_ISI
  244. end;
  245.  
  246. procedure GenSrtDoSrt (srtId : word; var srtStatus :word);
  247. begin
  248.     srtStatus := GenSrtDoSrtF(srtId)
  249. end;
  250.  
  251. function GenSrtDoSrtF (srtId : word) : word;
  252. begin
  253.   if ValidSrtId(srtId) then
  254.   begin
  255.     srtStatArr[srtId].srtState := GenSrtSt_RET;
  256.     GenSrtDoSrtF := GenSrtErr_NM;
  257.   end
  258.   else
  259.     GenSrtDoSrtF := GenSrtErr_ISI
  260. end;
  261.  
  262. procedure GenSrtRetrieve (var rec; srtId : word; var srtStatus : word);
  263. begin
  264.     srtStatus := GenSrtRetrieveF(rec, srtId)
  265. end;
  266.  
  267. function GenSrtRetrieveF (var rec; srtId : word) : word;
  268. var d, k : dataPtr;
  269.     dlen, klen : word;
  270. begin
  271.   if ValidSrtId(srtId) then
  272.     if srtStatArr[srtId].srtState = GenSrtSt_RET then
  273.       if srtStatArr[srtId].nbrRec > 0 then
  274.       begin
  275.         GenBinRetDelSmRec(srtRootArr[srtId], k, klen, d, dlen);
  276.         Move(d^, rec, dlen);
  277.         srtStatArr[srtId].nbrRec := srtStatArr[srtId].nbrRec - 1;
  278.         GenSrtRetrieveF := GenSrtErr_NM;
  279.       end
  280.       else
  281.         GenSrtretrieveF := GenSrtErr_ZR
  282.     else
  283.       GenSrtRetrieveF := GenSrtErr_ICO
  284.   else
  285.     GenSrtRetrieveF := GenSrtErr_ISI
  286. end;
  287.  
  288. procedure GenSrtEnd (srtId : word; var srtStatus : word);
  289. begin
  290.     srtStatus := GenSrtEndF(srtId)
  291. end;
  292.  
  293. function GenSrtEndF (srtId : word) : word;
  294. var d, k : dataPtr;
  295.     j, dlen, klen : word;
  296. begin
  297.   if ValidSrtId(srtId) then
  298.   begin
  299.     for j := 1 to srtStatArr[srtId].nbrRec do
  300.       GenBinRetDelSmRec(srtRootArr[srtId], d, dlen, k, klen);
  301.     srtStatArr[srtId].nbrRec := 0;
  302.     srtStatArr[srtId].srtState := GenSrtSt_NV
  303.   end
  304.   else
  305.     GenSrtEndF := GenSrtErr_ISI
  306. end;
  307.  
  308. procedure GenSrtStat (var srtStatus : SrtStatRec; srtId :word);
  309. begin
  310.      srtStatus := srtStatArr[srtId]
  311. end;
  312.  
  313. procedure GenSrtMsg (srtStatus : word; var srtString : SrtStr);
  314. begin
  315.      if srtStatus <= MAX_MSG then
  316.         srtString := SrtMsg[srtStatus + 1]
  317. end;
  318.  
  319. begin
  320.   for j := 1 to MAX_SRTS do
  321.     srtStatArr[j].srtState := GenSrtSt_NV;
  322. end.
  323.