Subversion Repositories oidplus

Rev

Rev 748 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit STRLIST;
  2.  
  3. (************************************************)
  4. (* STRLIST.PAS                                  *)
  5. (* Author:   Daniel Marschall                   *)
  6. (* Revision: 2022-10-10                         *)
  7. (* License:  Apache 2.0                         *)
  8. (* This file contains:                          *)
  9. (* - StringList implementation for Turbo Pascal *)
  10. (************************************************)
  11.  
  12. interface
  13.  
  14. type
  15.   PStringList = ^TStringList;
  16.   TStringList = record
  17.     init: boolean;
  18.     element: string;
  19.     next: PStringList;
  20.   end;
  21.  
  22. procedure CreateList(var list: PStringList);
  23. procedure FreeList(list: PStringList);
  24. function ListContains(list: PStringList; val: string): boolean;
  25. procedure ListClear(list: PStringList);
  26. function ListAppend(list: PStringList; str: string): integer;
  27. function ListCount(list: PStringList): integer;
  28. function ListDeleteElementByIndex(list: PStringlist; idx: integer): boolean;
  29. function ListDeleteElementByValue(list: PStringlist; val: string): boolean;
  30. function ListGetElement(list: PStringList; idx: integer): string;
  31. procedure ListSetElement(list: PStringList; idx: integer; value: string);
  32. procedure ListInsert(list: PStringlist; str: string; idx: integer);
  33. procedure ListSwapElement(list: PStringList; i, j: integer);
  34. procedure SplitStrToList(str: string; list: PStringList; separator: string);
  35. procedure OIDtoArcList(oid: string; list: PStringList);
  36. procedure ListBubbleSortNumericString(list: PStringList);
  37. function ListLoadFromFile(list: PStringList; filename: string): boolean;
  38. function ListSaveToFile(list: PStringList; filename: string): boolean;
  39.  
  40. implementation
  41.  
  42. uses
  43.   VtsFuncs;
  44.  
  45. procedure CreateList(var list: PStringList);
  46. begin
  47.   GetMem(list, SizeOf(TStringList));
  48.   list^.init := false;
  49.   list^.element := '';
  50.   list^.next := nil;
  51. end;
  52.  
  53. procedure FreeList(list: PStringList);
  54. begin
  55.   if list^.next <> nil then
  56.     FreeList(list^.Next);
  57.   FreeMem(list, SizeOf(TStringList));
  58. end;
  59.  
  60. function ListContains(list: PStringList; val: string): boolean;
  61. var
  62.   i: integer;
  63. begin
  64.   ListContains := false;
  65.   for i := 0 to ListCount(list)-1 do
  66.   begin
  67.     if ListGetElement(list, i) = val then
  68.     begin
  69.       ListContains := true;
  70.       break;
  71.     end;
  72.   end;
  73. end;
  74.  
  75. procedure ListClear(list: PStringList);
  76. begin
  77.   while ListCount(list) > 0 do
  78.   begin
  79.     ListDeleteElementByIndex(list, 0);
  80.   end;
  81. end;
  82.  
  83. function ListAppend(list: PStringList; str: string): integer;
  84. var
  85.   new: PStringList;
  86.   tmp: PStringList;
  87.   cnt: integer;
  88. begin
  89.   cnt := 0;
  90.   if not list^.init then
  91.   begin
  92.    list^.element := str;
  93.    list^.init := true;
  94.   end
  95.   else
  96.   begin
  97.     Inc(cnt);
  98.     GetMem(new, sizeof(TStringList));
  99.     new^.element := str;
  100.     new^.next := nil;
  101.     new^.init := true;
  102.  
  103.     tmp := list;
  104.     while tmp^.next <> nil do
  105.     begin
  106.       tmp := tmp^.next;
  107.       Inc(cnt);
  108.     end;
  109.  
  110.     tmp^.next := new;
  111.   end;
  112.  
  113.   ListAppend := cnt; (* Return the index where the new element was put *)
  114. end;
  115.  
  116. function ListCount(list: PStringList): integer;
  117. var
  118.   cnt: integer;
  119.   tmp: PStringList;
  120. begin
  121.   tmp := list;
  122.   cnt := 0;
  123.  
  124.   if tmp^.init then
  125.   begin
  126.     repeat
  127.       Inc(cnt);
  128.       tmp := tmp^.next;
  129.     until tmp = nil;
  130.   end;
  131.  
  132.   ListCount := cnt;
  133. end;
  134.  
  135. function ListDeleteElementByIndex(list: PStringlist; idx: integer): boolean;
  136. var
  137.   tmp, tmp2, prev: PStringList;
  138.   i: integer;
  139. begin
  140.   ListDeleteElementByIndex := false;
  141.   if idx < 0 then exit;
  142.   if idx > ListCount(list)-1 then exit;
  143.  
  144.   tmp := list;
  145.   prev := nil;
  146.   i := 0;
  147.   while i < idx do
  148.   begin
  149.     prev := tmp;
  150.     tmp := tmp^.next;
  151.     inc(i);
  152.   end;
  153.   if prev = nil then
  154.   begin
  155.     if tmp^.next = nil then
  156.     begin
  157.       tmp^.init := false;
  158.     end
  159.     else
  160.     begin
  161.       tmp^.init := true;
  162.       tmp^.element := tmp^.next^.element;
  163.       tmp2 := tmp^.next;
  164.       tmp^.next := tmp^.next^.next;
  165.       FreeMem(tmp2, SizeOf(TStringList));
  166.     end;
  167.   end
  168.   else
  169.   begin
  170.     prev^.next := tmp^.next;
  171.     FreeMem(tmp, SizeOf(TStringList));
  172.   end;
  173.  
  174.   ListDeleteElementByIndex := true;
  175. end;
  176.  
  177. function ListDeleteElementByValue(list: PStringlist; val: string): boolean;
  178. var
  179.   i: integer;
  180. begin
  181.   ListDeleteElementByValue := false;
  182.   for i := 0 to ListCount(list)-1 do
  183.   begin
  184.     if ListGetElement(list, i) = val then
  185.     begin
  186.       ListDeleteElementByValue := ListDeleteElementByIndex(list, i);
  187.       exit;
  188.     end;
  189.   end;
  190. end;
  191.  
  192. function ListGetElement(list: PStringList; idx: integer): string;
  193. var
  194.   tmp: PStringList;
  195.   i: integer;
  196. begin
  197.  if (idx < 0) or (idx > ListCount(list)-1) then
  198.   begin
  199.     ListGetElement := '';
  200.     Exit;
  201.   end;
  202.  
  203.   tmp := list;
  204.   i := 0;
  205.   while i < idx do
  206.   begin
  207.     tmp := tmp^.next;
  208.     inc(i);
  209.   end;
  210.  
  211.   ListGetElement := tmp^.element;
  212. end;
  213.  
  214. procedure ListSetElement(list: PStringList; idx: integer; value: string);
  215. var
  216.   tmp: PStringList;
  217.   i: integer;
  218. begin
  219.   if idx < 0 then exit;
  220.   if idx > ListCount(list)-1 then exit;
  221.  
  222.   tmp := list;
  223.   i := 0;
  224.   while i < idx do
  225.   begin
  226.     tmp := tmp^.next;
  227.     inc(i);
  228.   end;
  229.  
  230.   tmp^.element := value;
  231. end;
  232.  
  233. procedure ListInsert(list: PStringlist; str: string; idx: integer);
  234. var
  235.   tmp, new: PStringList;
  236.   i: integer;
  237. begin
  238.   if idx < 0 then exit;
  239.   if idx > ListCount(list)-1 then exit;
  240.  
  241.   tmp := list;
  242.   i := 0;
  243.   while i < idx do
  244.   begin
  245.     tmp := tmp^.next;
  246.     inc(i);
  247.   end;
  248.  
  249.   GetMem(new, sizeof(TStringList));
  250.   new^.init := true;
  251.   new^.next := tmp^.next;
  252.   new^.element := tmp^.element;
  253.  
  254.   tmp^.element := str;
  255.   tmp^.next := new;
  256.   tmp^.init := true;
  257. end;
  258.  
  259. procedure ListSwapElement(list: PStringList; i, j: integer);
  260. var
  261.   a, b: string;
  262. begin
  263.   a := ListGetElement(list, i);
  264.   b := ListGetElement(list, j);
  265.   ListSetElement(list, i, b);
  266.   ListSetElement(list, j, a);
  267. end;
  268.  
  269. procedure SplitStrToList(str: string; list: PStringList; separator: string);
  270. var
  271.   p: integer;
  272. begin
  273.   repeat
  274.     p := Pos(separator, str);
  275.     if p = 0 then
  276.     begin
  277.       ListAppend(list, str);
  278.       Exit;
  279.     end
  280.     else
  281.     begin
  282.       ListAppend(list, Copy(str, 1, p-1));
  283.       str := copy(str, p+Length(separator), Length(str)-p);
  284.     end;
  285.   until str = '';
  286. end;
  287.  
  288. procedure OIDtoArcList(oid: string; list: PStringList);
  289. begin
  290.   SplitStrToList(oid, list, '.');
  291. end;
  292.  
  293. procedure ListBubbleSortNumericString(list: PStringList);
  294. var
  295.   n, i: integer;
  296.   a, b: string;
  297.   swapped: boolean;
  298. begin
  299.   n := ListCount(list);
  300.   while n>1 do
  301.   begin
  302.     i := 0;
  303.     swapped := false;
  304.     while i<n-1 do
  305.     begin
  306.       a := ListGetElement(list, i);
  307.       b := ListGetElement(list, i+1);
  308.       if CompareNumericString(a, b) > 0 then
  309.       begin
  310.         ListSwapElement(list, i, i+1);
  311.         swapped := true;
  312.       end;
  313.       Inc(i);
  314.     end;
  315.     if not swapped then break;
  316.     Dec(n);
  317.   end;
  318. end;
  319.  
  320. function ListLoadFromFile(list: PStringList; filename: string): boolean;
  321. var
  322.   f: Text;
  323.   s: string;
  324. begin
  325.   Assign(f, filename);
  326.  
  327.   {$I-}
  328.   Reset(f);
  329.   {$I+}
  330.   if IoResult <> 0 then
  331.   begin
  332.     ListLoadFromFile := false;
  333.     (* Must not call Close(f) if file was never opened *)
  334.     Exit;
  335.   end;
  336.  
  337.   ListClear(list);
  338.  
  339.   while not EOF(f) do
  340.   begin
  341.     ReadLn(f, s);
  342.     ListAppend(list, s);
  343.   end;
  344.  
  345.   Close(f);
  346.   ListLoadFromFile := true;
  347. end;
  348.  
  349. function ListSaveToFile(list: PStringList; filename: string): boolean;
  350. var
  351.   f: Text;
  352.   i: integer;
  353.   s: string;
  354. begin
  355.   Assign(f, filename);
  356.  
  357.   {$I-}
  358.   Rewrite(f);
  359.   {$I+}
  360.   if IoResult <> 0 then
  361.   begin
  362.     ListSaveToFile := false;
  363.     (* Must not call Close(f) if file was never opened *)
  364.     Exit;
  365.   end;
  366.  
  367.   for i := 0 to ListCount(list)-1 do
  368.   begin
  369.     s := ListGetElement(list, i);
  370.     WriteLn(f, s);
  371.   end;
  372.  
  373.   Close(f);
  374.   ListSaveToFile := true;
  375. end;
  376.  
  377. end.
  378.