Subversion Repositories oidplus

Rev

Rev 740 | Rev 748 | Go to most recent revision | 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-02-16                         *)
  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 then exit;
  198.   if idx > ListCount(list)-1 then exit;
  199.  
  200.   tmp := list;
  201.   i := 0;
  202.   while i < idx do
  203.   begin
  204.     tmp := tmp^.next;
  205.     inc(i);
  206.   end;
  207.  
  208.   ListGetElement := tmp^.element;
  209. end;
  210.  
  211. procedure ListSetElement(list: PStringList; idx: integer; value: string);
  212. var
  213.   tmp: PStringList;
  214.   i: integer;
  215. begin
  216.   if idx < 0 then exit;
  217.   if idx > ListCount(list)-1 then exit;
  218.  
  219.   tmp := list;
  220.   i := 0;
  221.   while i < idx do
  222.   begin
  223.     tmp := tmp^.next;
  224.     inc(i);
  225.   end;
  226.  
  227.   tmp^.element := value;
  228. end;
  229.  
  230. procedure ListInsert(list: PStringlist; str: string; idx: integer);
  231. var
  232.   tmp, new: PStringList;
  233.   i: integer;
  234. begin
  235.   if idx < 0 then exit;
  236.   if idx > ListCount(list)-1 then exit;
  237.  
  238.   tmp := list;
  239.   i := 0;
  240.   while i < idx do
  241.   begin
  242.     tmp := tmp^.next;
  243.     inc(i);
  244.   end;
  245.  
  246.   GetMem(new, sizeof(TStringList));
  247.   new^.init := true;
  248.   new^.next := tmp^.next;
  249.   new^.element := tmp^.element;
  250.  
  251.   tmp^.element := str;
  252.   tmp^.next := new;
  253.   tmp^.init := true;
  254. end;
  255.  
  256. procedure ListSwapElement(list: PStringList; i, j: integer);
  257. var
  258.   a, b: string;
  259. begin
  260.   a := ListGetElement(list, i);
  261.   b := ListGetElement(list, j);
  262.   ListSetElement(list, i, b);
  263.   ListSetElement(list, j, a);
  264. end;
  265.  
  266. procedure SplitStrToList(str: string; list: PStringList; separator: string);
  267. var
  268.   p: integer;
  269. begin
  270.   str := str + separator;
  271.   repeat
  272.     p := Pos(separator, str);
  273.     ListAppend(list, Copy(str, 1, p-1));
  274.     str := copy(str, p+Length(separator), Length(str)-p);
  275.   until str = '';
  276. end;
  277.  
  278. procedure OIDtoArcList(oid: string; list: PStringList);
  279. begin
  280.   SplitStrToList(oid, list, '.');
  281. end;
  282.  
  283. procedure ListBubbleSortNumericString(list: PStringList);
  284. var
  285.   n, i: integer;
  286.   a, b: string;
  287.   swapped: boolean;
  288. begin
  289.   n := ListCount(list);
  290.   while n>1 do
  291.   begin
  292.     i := 0;
  293.     swapped := false;
  294.     while i<n-1 do
  295.     begin
  296.       a := ListGetElement(list, i);
  297.       b := ListGetElement(list, i+1);
  298.       if CompareNumericString(a, b) > 0 then
  299.       begin
  300.         ListSwapElement(list, i, i+1);
  301.         swapped := true;
  302.       end;
  303.       Inc(i);
  304.     end;
  305.     if not swapped then break;
  306.     Dec(n);
  307.   end;
  308. end;
  309.  
  310. function ListLoadFromFile(list: PStringList; filename: string): boolean;
  311. var
  312.   f: Text;
  313.   s: string;
  314. begin
  315.   Assign(f, filename);
  316.  
  317.   {$I-}
  318.   Reset(f);
  319.   {$I+}
  320.   if IoResult <> 0 then
  321.   begin
  322.     ListLoadFromFile := false;
  323.     (* Must not call Close(f) if file was never opened *)
  324.     Exit;
  325.   end;
  326.  
  327.   ListClear(list);
  328.  
  329.   while not EOF(f) do
  330.   begin
  331.     ReadLn(f, s);
  332.     ListAppend(list, s);
  333.   end;
  334.  
  335.   Close(f);
  336.   ListLoadFromFile := true;
  337. end;
  338.  
  339. function ListSaveToFile(list: PStringList; filename: string): boolean;
  340. var
  341.   f: Text;
  342.   i: integer;
  343.   s: string;
  344. begin
  345.   Assign(f, filename);
  346.  
  347.   {$I-}
  348.   Rewrite(f);
  349.   {$I+}
  350.   if IoResult <> 0 then
  351.   begin
  352.     ListSaveToFile := false;
  353.     (* Must not call Close(f) if file was never opened *)
  354.     Exit;
  355.   end;
  356.  
  357.   for i := 0 to ListCount(list)-1 do
  358.   begin
  359.     s := ListGetElement(list, i);
  360.     WriteLn(f, s);
  361.   end;
  362.  
  363.   Close(f);
  364.   ListSaveToFile := true;
  365. end;
  366.  
  367. end.
  368.