Subversion Repositories oidplus

Rev

Rev 747 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
733 daniel-mar 1
unit STRLIST;
2
 
3
(************************************************)
4
(* STRLIST.PAS                                  *)
5
(* Author:   Daniel Marschall                   *)
748 daniel-mar 6
(* Revision: 2022-02-19                         *)
733 daniel-mar 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
 
735 daniel-mar 22
procedure CreateList(var list: PStringList);
733 daniel-mar 23
procedure FreeList(list: PStringList);
24
function ListContains(list: PStringList; val: string): boolean;
25
procedure ListClear(list: PStringList);
735 daniel-mar 26
function ListAppend(list: PStringList; str: string): integer;
733 daniel-mar 27
function ListCount(list: PStringList): integer;
737 daniel-mar 28
function ListDeleteElementByIndex(list: PStringlist; idx: integer): boolean;
29
function ListDeleteElementByValue(list: PStringlist; val: string): boolean;
733 daniel-mar 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);
747 daniel-mar 37
function ListLoadFromFile(list: PStringList; filename: string): boolean;
38
function ListSaveToFile(list: PStringList; filename: string): boolean;
733 daniel-mar 39
 
40
implementation
41
 
42
uses
43
  VtsFuncs;
44
 
735 daniel-mar 45
procedure CreateList(var list: PStringList);
733 daniel-mar 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
740 daniel-mar 56
    FreeList(list^.Next);
733 daniel-mar 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
737 daniel-mar 79
    ListDeleteElementByIndex(list, 0);
733 daniel-mar 80
  end;
81
end;
82
 
735 daniel-mar 83
function ListAppend(list: PStringList; str: string): integer;
733 daniel-mar 84
var
85
  new: PStringList;
86
  tmp: PStringList;
735 daniel-mar 87
  cnt: integer;
733 daniel-mar 88
begin
735 daniel-mar 89
  cnt := 0;
733 daniel-mar 90
  if not list^.init then
91
  begin
92
   list^.element := str;
93
   list^.init := true;
94
  end
95
  else
96
  begin
735 daniel-mar 97
    Inc(cnt);
733 daniel-mar 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;
735 daniel-mar 107
      Inc(cnt);
733 daniel-mar 108
    end;
109
 
110
    tmp^.next := new;
111
  end;
735 daniel-mar 112
 
113
  ListAppend := cnt; (* Return the index where the new element was put *)
733 daniel-mar 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
 
737 daniel-mar 135
function ListDeleteElementByIndex(list: PStringlist; idx: integer): boolean;
733 daniel-mar 136
var
137
  tmp, tmp2, prev: PStringList;
138
  i: integer;
139
begin
737 daniel-mar 140
  ListDeleteElementByIndex := false;
733 daniel-mar 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;
737 daniel-mar 173
 
174
  ListDeleteElementByIndex := true;
733 daniel-mar 175
end;
176
 
737 daniel-mar 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
 
733 daniel-mar 192
function ListGetElement(list: PStringList; idx: integer): string;
193
var
194
  tmp: PStringList;
195
  i: integer;
196
begin
748 daniel-mar 197
 if (idx < 0) or (idx > ListCount(list)-1) then
198
  begin
199
    ListGetElement := '';
200
    Exit;
201
  end;
733 daniel-mar 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
  str := str + separator;
274
  repeat
275
    p := Pos(separator, str);
276
    ListAppend(list, Copy(str, 1, p-1));
277
    str := copy(str, p+Length(separator), Length(str)-p);
278
  until str = '';
279
end;
280
 
281
procedure OIDtoArcList(oid: string; list: PStringList);
282
begin
283
  SplitStrToList(oid, list, '.');
284
end;
285
 
286
procedure ListBubbleSortNumericString(list: PStringList);
287
var
288
  n, i: integer;
289
  a, b: string;
740 daniel-mar 290
  swapped: boolean;
733 daniel-mar 291
begin
292
  n := ListCount(list);
293
  while n>1 do
294
  begin
295
    i := 0;
740 daniel-mar 296
    swapped := false;
733 daniel-mar 297
    while i<n-1 do
298
    begin
299
      a := ListGetElement(list, i);
300
      b := ListGetElement(list, i+1);
301
      if CompareNumericString(a, b) > 0 then
302
      begin
303
        ListSwapElement(list, i, i+1);
740 daniel-mar 304
        swapped := true;
733 daniel-mar 305
      end;
306
      Inc(i);
307
    end;
740 daniel-mar 308
    if not swapped then break;
733 daniel-mar 309
    Dec(n);
310
  end;
311
end;
312
 
747 daniel-mar 313
function ListLoadFromFile(list: PStringList; filename: string): boolean;
314
var
315
  f: Text;
316
  s: string;
317
begin
318
  Assign(f, filename);
319
 
320
  {$I-}
321
  Reset(f);
322
  {$I+}
323
  if IoResult <> 0 then
324
  begin
325
    ListLoadFromFile := false;
326
    (* Must not call Close(f) if file was never opened *)
327
    Exit;
328
  end;
329
 
330
  ListClear(list);
331
 
332
  while not EOF(f) do
333
  begin
334
    ReadLn(f, s);
335
    ListAppend(list, s);
336
  end;
337
 
338
  Close(f);
339
  ListLoadFromFile := true;
340
end;
341
 
342
function ListSaveToFile(list: PStringList; filename: string): boolean;
343
var
344
  f: Text;
345
  i: integer;
346
  s: string;
347
begin
348
  Assign(f, filename);
349
 
350
  {$I-}
351
  Rewrite(f);
352
  {$I+}
353
  if IoResult <> 0 then
354
  begin
355
    ListSaveToFile := false;
356
    (* Must not call Close(f) if file was never opened *)
357
    Exit;
358
  end;
359
 
360
  for i := 0 to ListCount(list)-1 do
361
  begin
362
    s := ListGetElement(list, i);
363
    WriteLn(f, s);
364
  end;
365
 
366
  Close(f);
367
  ListSaveToFile := true;
368
end;
369
 
733 daniel-mar 370
end.