Subversion Repositories oidplus

Rev

Rev 740 | Rev 748 | 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                   *)
747 daniel-mar 6
(* Revision: 2022-02-16                         *)
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
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;
740 daniel-mar 287
  swapped: boolean;
733 daniel-mar 288
begin
289
  n := ListCount(list);
290
  while n>1 do
291
  begin
292
    i := 0;
740 daniel-mar 293
    swapped := false;
733 daniel-mar 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);
740 daniel-mar 301
        swapped := true;
733 daniel-mar 302
      end;
303
      Inc(i);
304
    end;
740 daniel-mar 305
    if not swapped then break;
733 daniel-mar 306
    Dec(n);
307
  end;
308
end;
309
 
747 daniel-mar 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
 
733 daniel-mar 367
end.