Subversion Repositories oidplus

Rev

Rev 748 | 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                   *)
992 daniel-mar 6
(* Revision: 2022-10-10                         *)
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
  repeat
274
    p := Pos(separator, str);
992 daniel-mar 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;
733 daniel-mar 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;
740 daniel-mar 297
  swapped: boolean;
733 daniel-mar 298
begin
299
  n := ListCount(list);
300
  while n>1 do
301
  begin
302
    i := 0;
740 daniel-mar 303
    swapped := false;
733 daniel-mar 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);
740 daniel-mar 311
        swapped := true;
733 daniel-mar 312
      end;
313
      Inc(i);
314
    end;
740 daniel-mar 315
    if not swapped then break;
733 daniel-mar 316
    Dec(n);
317
  end;
318
end;
319
 
747 daniel-mar 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
 
733 daniel-mar 377
end.