Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
717 mikedld 1
;;================================================================================================;;
2
;;//// libini.asm //// (c) mike.dld, 2006-2008 ///////////////////////////////////////////////////;;
3
;;================================================================================================;;
4
;;                                                                                                ;;
5
;; This file is part of Common development libraries (Libs-Dev).                                  ;;
6
;;                                                                                                ;;
7
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
8
;; General Public License as published by the Free Software Foundation, either version 3 of the   ;;
9
;; License, or (at your option) any later version.                                                ;;
10
;;                                                                                                ;;
11
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
12
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
13
;; General Public License for more details.                                                       ;;
14
;;                                                                                                ;;
15
;; You should have received a copy of the GNU General Public License along with Libs-Dev. If not, ;;
16
;; see .                                                            ;;
17
;;                                                                                                ;;
18
;;================================================================================================;;
19
;;                                                                                                ;;
20
;; 2008-02-07 (mike.dld)                                                                          ;;
21
;;   changes:                                                                                     ;;
22
;;     - renamed all *.aux.* to *._.* to match overall libraries design                           ;;
23
;; 2007-09-26 (mike.dld)                                                                          ;;
24
;;   bug-fixes:                                                                                   ;;
25
;;     - value was not correctly trimmed (reported by diamond)                                    ;;
26
;; 2007-08-01 (mike.dld)                                                                          ;;
27
;;   bug-fixes:                                                                                   ;;
28
;;     - serious defect in ini.set_str causing displaced write operations                         ;;
29
;;       (reported by diamond)                                                                    ;;
30
;;     - another serious defect in ini.enum_keys introduced with refactoring                      ;;
31
;;   changes:                                                                                     ;;
32
;;     - callback for enum_keys now takes additional parameter - key value                        ;;
33
;;     - handling trailing spaces in section/key/value                                            ;;
34
;; 2007-05-19 (mike.dld)                                                                          ;;
35
;;   bug-fixes:                                                                                   ;;
36
;;     - last char still wasn't read correctly                                                    ;;
37
;;     - digits of number were reversed when using ini.set_int                                    ;;
38
;;     - now using 'ini.aux.unget_char' instead of dangerous 'dec esi'                            ;;
39
;;   changes:                                                                                     ;;
40
;;     - all non-public functions now start with ini.aux.*                                        ;;
41
;;     - added ini.enum_sections and ini.enum_keys                                                ;;
42
;;     - removed ini.query_sec (use ini.enum_* instead)                                           ;;
43
;;                                                                                                ;;
44
;;================================================================================================;;
45
 
46
format MS COFF
47
 
48
public @EXPORT as 'EXPORTS'
49
 
50
include '../../../../proc32.inc'
51
include '../../../../macros.inc'
52
include '../libio/libio.inc'
53
purge section ; mov,add,sub
54
 
55
section '.flat' code readable align 16
56
 
57
include 'libini_p.inc'
58
 
59
mem.alloc   dd ?
60
mem.free    dd ?
61
mem.realloc dd ?
62
dll.load    dd ?
63
 
64
;;================================================================================================;;
65
proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
66
;;------------------------------------------------------------------------------------------------;;
67
;? Library entry point (called after library load)                                                ;;
68
;;------------------------------------------------------------------------------------------------;;
69
;> eax = pointer to memory allocation routine                                                     ;;
70
;> ebx = pointer to memory freeing routine                                                        ;;
71
;> ecx = pointer to memory reallocation routine                                                   ;;
72
;> edx = pointer to library loading routine                                                       ;;
73
;;------------------------------------------------------------------------------------------------;;
74
;< eax = 1 (fail) / 0 (ok) (library initialization result)                                        ;;
75
;;================================================================================================;;
76
	mov	[mem.alloc], eax
77
	mov	[mem.free], ebx
78
	mov	[mem.realloc], ecx
79
	mov	[dll.load], edx
80
 
81
	invoke	dll.load, @IMPORT
82
	or	eax, eax
83
	jz	.ok
84
 
85
	xor	eax, eax
86
	inc	eax
87
	ret
88
 
89
  .ok:	xor	eax,eax
90
	ret
91
endp
92
 
93
;;================================================================================================;;
94
proc ini._.unget_char _f ;////////////////////////////////////////////////////////////////////////;;
95
;;------------------------------------------------------------------------------------------------;;
96
;? --- TBD ---                                                                                    ;;
97
;;------------------------------------------------------------------------------------------------;;
98
;> --- TBD ---                                                                                    ;;
99
;;------------------------------------------------------------------------------------------------;;
100
;< --- TBD ---                                                                                    ;;
101
;;================================================================================================;;
102
	;push    ecx
103
	;mov     ecx,[f]
104
	;inc     [ecx+INIFILE.cnt]
105
	;dec     esi
106
	;pop     ecx
107
	;ret
108
	push	eax ecx
109
	mov	ecx, [_f]
110
	inc	[ecx + IniFile.cnt]
111
	dec	esi
112
	mov	eax, [ecx + IniFile.bsize]
113
	cmp	[ecx + IniFile.cnt], eax
114
	jle	@f
115
	stdcall ini._.unload_block, [_f]
116
    @@: ;mov     al,[esi-1]
117
	pop	ecx eax
118
	ret
119
endp
120
 
121
;;================================================================================================;;
122
proc ini._.get_char _f ;//////////////////////////////////////////////////////////////////////////;;
123
;;------------------------------------------------------------------------------------------------;;
124
;? --- TBD ---                                                                                    ;;
125
;;------------------------------------------------------------------------------------------------;;
126
;> --- TBD ---                                                                                    ;;
127
;;------------------------------------------------------------------------------------------------;;
128
;< --- TBD ---                                                                                    ;;
129
;;================================================================================================;;
130
	mov	ecx, [_f]
131
	dec	[ecx + IniFile.cnt]
132
	jns	@f
133
	stdcall ini._.preload_block, [_f]
134
	dec	[ecx + IniFile.cnt]
135
    @@: lodsb
136
	ret
137
endp
138
 
139
;;================================================================================================;;
140
proc ini._.skip_nonblanks _f ;////////////////////////////////////////////////////////////////////;;
141
;;------------------------------------------------------------------------------------------------;;
142
;? --- TBD ---                                                                                    ;;
143
;;------------------------------------------------------------------------------------------------;;
144
;> --- TBD ---                                                                                    ;;
145
;;------------------------------------------------------------------------------------------------;;
146
;< --- TBD ---                                                                                    ;;
147
;;================================================================================================;;
148
	mov	ecx, [_f]
149
    @@: stdcall ini._.get_char, [_f]
150
	cmp	al, 32
151
	je	@b
152
	cmp	al, 13
153
	je	@b
154
	cmp	al, 10
155
	je	@b
156
	cmp	al, 9
157
	je	@b
158
    @@: stdcall ini._.unget_char, [_f]
159
	;inc     [ecx+INIFILE.cnt]
160
	ret
161
endp
162
 
163
;;================================================================================================;;
164
proc ini._.skip_spaces _f ;///////////////////////////////////////////////////////////////////////;;
165
;;------------------------------------------------------------------------------------------------;;
166
;? --- TBD ---                                                                                    ;;
167
;;------------------------------------------------------------------------------------------------;;
168
;> --- TBD ---                                                                                    ;;
169
;;------------------------------------------------------------------------------------------------;;
170
;< --- TBD ---                                                                                    ;;
171
;;================================================================================================;;
172
	mov	ecx, [_f]
173
    @@: stdcall ini._.get_char, [_f]
174
	cmp	al, 32
175
	je	@b
176
	cmp	al, 9
177
	je	@b
178
    @@: stdcall ini._.unget_char, [_f]
179
	;inc     [ecx+INIFILE.cnt]
180
	ret
181
endp
182
 
183
;;================================================================================================;;
184
proc ini._.skip_line _f ;/////////////////////////////////////////////////////////////////////////;;
185
;;------------------------------------------------------------------------------------------------;;
186
;? --- TBD ---                                                                                    ;;
187
;;------------------------------------------------------------------------------------------------;;
188
;> --- TBD ---                                                                                    ;;
189
;;------------------------------------------------------------------------------------------------;;
190
;< --- TBD ---                                                                                    ;;
191
;;================================================================================================;;
192
	mov	ecx, [_f]
193
    @@: stdcall ini._.get_char, [_f]
194
	or	al, al
195
	jz	@f
196
	cmp	al, 13
197
	je	@f
198
	cmp	al, 10
199
	jne	@b
200
    @@: stdcall ini._.unget_char, [_f]
201
	;inc     [ecx+INIFILE.cnt]
202
	ret
203
endp
204
 
205
;;================================================================================================;;
206
proc ini._.unload_block _f ;//////////////////////////////////////////////////////////////////////;;
207
;;------------------------------------------------------------------------------------------------;;
208
;? --- TBD ---                                                                                    ;;
209
;;------------------------------------------------------------------------------------------------;;
210
;> --- TBD ---                                                                                    ;;
211
;;------------------------------------------------------------------------------------------------;;
212
;< --- TBD ---                                                                                    ;;
213
;;================================================================================================;;
214
	push	eax ebx ecx
215
	mov	ebx, [_f]
216
	mov	eax, [ebx + IniFile.pos]
217
	add	eax, -ini.BLOCK_SIZE
218
	invoke	file.seek, [ebx + IniFile.fh], SEEK_SET, eax
219
	stdcall ini._.preload_block, ebx
220
	add	esi, eax ; ini.BLOCK_SIZE
221
	mov	[ebx + IniFile.cnt], 0
222
	pop	ecx ebx eax
223
	ret
224
endp
225
 
226
;;================================================================================================;;
227
proc ini._.preload_block _f ;/////////////////////////////////////////////////////////////////////;;
228
;;------------------------------------------------------------------------------------------------;;
229
;? --- TBD ---                                                                                    ;;
230
;;------------------------------------------------------------------------------------------------;;
231
;> --- TBD ---                                                                                    ;;
232
;;------------------------------------------------------------------------------------------------;;
233
;< --- TBD ---                                                                                    ;;
234
;;================================================================================================;;
235
	push	eax ebx ecx
236
	mov	ebx, [_f]
237
    @@: mov	esi, [ebx + IniFile.buf]
238
	push	edi
239
	mov	edi, esi
240
	mov	ecx, ini.BLOCK_SIZE / 4
241
	xor	eax, eax
242
	rep	stosd
243
	pop	edi
244
	invoke	file.tell, [ebx + IniFile.fh]
245
	mov	[ebx + IniFile.pos], eax
246
	invoke	file.read, [ebx + IniFile.fh], esi, ini.BLOCK_SIZE
247
	mov	esi,[ebx + IniFile.buf]
248
	cmp	eax,ini.BLOCK_SIZE
249
	jl	@f
250
	;dec     eax
251
    @@: mov	[ebx + IniFile.cnt], eax;ini.BLOCK_SIZE-1
252
	mov	[ebx + IniFile.bsize], eax
253
	pop	ecx ebx eax
254
	ret
255
endp
256
 
257
;;================================================================================================;;
258
proc ini._.reload_block _f ;//////////////////////////////////////////////////////////////////////;;
259
;;------------------------------------------------------------------------------------------------;;
260
;? --- TBD ---                                                                                    ;;
261
;;------------------------------------------------------------------------------------------------;;
262
;> --- TBD ---                                                                                    ;;
263
;;------------------------------------------------------------------------------------------------;;
264
;< --- TBD ---                                                                                    ;;
265
;;================================================================================================;;
266
	push	eax ebx ecx
267
	mov	ebx, [_f]
268
	push	[ebx + IniFile.bsize]
269
	push	esi [ebx + IniFile.cnt]
270
	invoke	file.seek, [ebx + IniFile.fh], SEEK_SET, [ebx + IniFile.pos]
271
	stdcall ini._.preload_block, ebx
272
	pop	[ebx + IniFile.cnt] esi
273
	pop	eax
274
	sub	eax,[ebx + IniFile.bsize]
275
	sub	[ebx + IniFile.cnt], eax
276
	pop	ecx ebx eax
277
	ret
278
endp
279
 
280
; f_info - contains current file block number
281
; esi    - position in block from where to shift
282
; ecx    - number of bytes to shift by
283
 
284
;;================================================================================================;;
285
proc ini._.shift_content _f, _delta ;/////////////////////////////////////////////////////////////;;
286
;;------------------------------------------------------------------------------------------------;;
287
;? Shift file content starting from cursor position (~ delete)                                    ;;
288
;? Content is copied by 'delta' bytes up/down                                                     ;;
289
;;------------------------------------------------------------------------------------------------;;
290
;> --- TBD ---                                                                                    ;;
291
;;------------------------------------------------------------------------------------------------;;
292
;< eax = 0 (ok) / -1 (fail)                                                                       ;;
293
;;================================================================================================;;
294
locals
295
  buf dd ?
296
endl
297
 
298
	xor	eax, eax
299
	cmp	[_delta], 0
300
	je	.skip
301
 
302
	push	ebx ecx
303
	invoke	mem.alloc, ini.BLOCK_SIZE
304
	or	eax, eax
305
	jz	.fail
306
	mov	[buf], eax
307
 
308
	cmp	[_delta], 0
309
	jl	.down
310
 
311
	mov	ebx, [_f]
312
	mov	ecx, [ebx + IniFile.cnt]
313
	mov	ebx, [ebx + IniFile.fh]
314
	invoke	file.tell, ebx
315
;       push    eax
316
	sub	eax, ecx
317
;       dec     eax
318
	invoke	file.seek, ebx, SEEK_SET, eax
319
    @@: invoke	file.seek, ebx, SEEK_CUR, [_delta]
320
	invoke	file.eof?, ebx
321
	or	eax, eax
322
	jnz	.done
323
	invoke	file.read, ebx, [buf], ini.BLOCK_SIZE
324
	mov	ecx, eax
325
	mov	eax, [_delta]
326
	neg	eax
327
	sub	eax,ecx;ini.BLOCK_SIZE
328
	invoke	file.seek,ebx,SEEK_CUR,eax
329
	invoke	file.write,ebx,[buf],ecx;ini.BLOCK_SIZE
330
	jmp	@b
331
  .done:
332
	mov	eax, [_delta]
333
	neg	eax
334
	invoke	file.seek, ebx, SEEK_CUR, eax
335
	invoke	file.seteof, ebx
336
;       pop     eax
337
;       invoke  file.seek, ebx, SEEK_SET;, eax
338
	stdcall ini._.reload_block, [_f]
339
	invoke	mem.free, [buf]
340
	pop	ecx ebx
341
  .skip:
342
	ret
343
  .fail:
344
	or	eax, -1
345
	pop	ecx ebx
346
	ret
347
 
348
  .down:
349
	neg	[_delta]
350
 
351
	mov	ebx, [_f]
352
	mov	ecx, [ebx + IniFile.cnt]
353
	mov	ebx, [ebx + IniFile.fh]
354
	invoke	file.tell, ebx
355
;       push    eax
356
	sub	eax, ecx
357
	lea	edx, [eax - 1]
358
	push	edx
359
    @@: invoke	file.seek, ebx, SEEK_SET, edx
360
	invoke	file.eof?, ebx
361
	or	eax, eax
362
	jnz	@f
363
	add	edx, ini.BLOCK_SIZE
364
	jmp	@b
365
    @@: cmp	edx, [esp]
366
	je	.skip.2
367
	add	edx, -ini.BLOCK_SIZE
368
	cmp	edx, [esp]
369
	jl	@f
370
	invoke	file.seek, ebx, SEEK_SET, edx
371
	invoke	file.read, ebx, [buf], ini.BLOCK_SIZE
372
	mov	ecx, eax
373
	mov	eax, [_delta]
374
	sub	eax, ecx
375
	invoke	file.seek, ebx, SEEK_CUR, eax
376
	invoke	file.write, ebx, [buf], ecx
377
	jmp	@b
378
    @@:
379
  .skip.2:
380
	add	esp, 4
381
;       mov     eax,[delta]
382
;       neg     eax
383
;       invoke  file.seek,ebx,SEEK_CUR,eax
384
;       pop     eax
385
;       invoke  file.seek,ebx,SEEK_SET;,eax
386
	stdcall ini._.reload_block, [_f]
387
	invoke	mem.free, [buf]
388
	pop	ecx ebx
389
	ret
390
endp
391
 
392
;;================================================================================================;;
393
proc ini._.get_value_length _f ;//////////////////////////////////////////////////////////////////;;
394
;;------------------------------------------------------------------------------------------------;;
395
;? --- TBD ---                                                                                    ;;
396
;;------------------------------------------------------------------------------------------------;;
397
;> --- TBD ---                                                                                    ;;
398
;;------------------------------------------------------------------------------------------------;;
399
;< --- TBD ---                                                                                    ;;
400
;;================================================================================================;;
401
	push	ebx ecx edx eax
402
	mov	ebx, [_f]
403
	invoke	file.tell, [ebx + IniFile.fh]
404
	push	esi [ebx + IniFile.cnt] [ebx + IniFile.pos]
405
	sub	eax, [ebx + IniFile.cnt]
406
	mov	edx, eax
407
 
408
	stdcall ini._.skip_line, [_f]
409
	invoke	file.tell, [ebx + IniFile.fh]
410
	sub	eax, [ebx + IniFile.cnt]
411
	sub	eax, edx
412
	mov	[esp + 4 * 3], eax
413
 
414
;       pop     eax
415
	invoke	file.seek, [ebx + IniFile.fh], SEEK_SET;, eax
416
	stdcall ini._.preload_block, [_f]
417
	pop	[ebx + IniFile.cnt] esi
418
	pop	eax edx ecx ebx
419
	ret
420
endp
421
 
422
;;================================================================================================;;
423
proc ini._.string_copy ;//////////////////////////////////////////////////////////////////////////;;
424
;;------------------------------------------------------------------------------------------------;;
425
;? --- TBD ---                                                                                    ;;
426
;;------------------------------------------------------------------------------------------------;;
427
;> --- TBD ---                                                                                    ;;
428
;;------------------------------------------------------------------------------------------------;;
429
;< --- TBD ---                                                                                    ;;
430
;;================================================================================================;;
431
    @@: lodsb
432
	or	al, al
433
	jz	@f
434
	stosb
435
	jmp	@b
436
    @@: ret
437
endp
438
 
439
;;================================================================================================;;
440
proc ini._.find_next_section _f ;/////////////////////////////////////////////////////////////////;;
441
;;------------------------------------------------------------------------------------------------;;
442
;? --- TBD ---                                                                                    ;;
443
;;------------------------------------------------------------------------------------------------;;
444
;> --- TBD ---                                                                                    ;;
445
;;------------------------------------------------------------------------------------------------;;
446
;< --- TBD ---                                                                                    ;;
447
;;================================================================================================;;
448
	push	ebx edi
449
 
450
    @@: stdcall ini._.skip_nonblanks, [_f]
451
	cmp	al, '['
452
	je	@f
453
	or	al, al
454
	jz	.exit_error
455
	stdcall ini._.skip_line, [_f]
456
	or	al, al
457
	jz	.exit_error
458
	jmp	@b
459
    @@:
460
	pop	edi ebx
461
	xor	eax, eax
462
	ret
463
 
464
  .exit_error:
465
	pop	edi ebx
466
	or	eax, -1
467
	ret
468
endp
469
 
470
;;================================================================================================;;
471
proc ini._.find_section _f, _sec_name ;///////////////////////////////////////////////////////////;;
472
;;------------------------------------------------------------------------------------------------;;
473
;? Find section in file                                                                           ;;
474
;? Search is performed from the beginning of file                                                 ;;
475
;;------------------------------------------------------------------------------------------------;;
476
;> --- TBD ---                                                                                    ;;
477
;;------------------------------------------------------------------------------------------------;;
478
;< eax = 0 (ok) / -1 (fail)                                                                       ;;
479
;< [f.pos] = new cursor position (right after ']' char if eax = 0, at the end of file otherwise)  ;;
480
;;================================================================================================;;
481
	push	ebx edi
482
 
483
	mov	ecx, [_f]
484
	invoke	file.seek, [ecx + IniFile.fh], SEEK_SET, 0
485
	stdcall ini._.preload_block, [_f]
486
 
487
  .next_section:
488
	stdcall ini._.find_next_section, [_f]
489
	or	eax, eax
490
	jnz	.exit_error
491
 
492
	stdcall ini._.get_char, [_f]
493
;       inc     esi
494
;       dec     [ecx + IniFile.cnt]
495
	stdcall ini._.skip_spaces, [_f]
496
	mov	edi, [_sec_name]
497
    @@: stdcall ini._.get_char, [_f]
498
	cmp	al, ']'
499
	je	@f
500
	or	al, al
501
	jz	.exit_error
502
	cmp	al, 13
503
	je	.next_section
504
	cmp	al, 10
505
	je	.next_section
506
	scasb
507
	je	@b
508
	cmp	byte[edi - 1], 0
509
	jne	.next_section
510
	dec	edi
511
	stdcall ini._.unget_char, [_f]
512
	stdcall ini._.skip_spaces, [_f]
513
	stdcall ini._.get_char, [_f]
514
	cmp	al, ']'
515
	jne	.next_section
516
    @@:
517
	cmp	byte[edi], 0
518
	jne	.next_section
519
	pop	edi ebx
520
	xor	eax, eax
521
	ret
522
 
523
  .exit_error:
524
	pop	edi ebx
525
	or	eax, -1
526
	ret
527
endp
528
 
529
;;================================================================================================;;
530
proc ini._.find_key _f, _key_name ;///////////////////////////////////////////////////////////////;;
531
;;------------------------------------------------------------------------------------------------;;
532
;? Find key in section                                                                            ;;
533
;? Search is performed within current section starting from cursor position                       ;;
534
;;------------------------------------------------------------------------------------------------;;
535
;> --- TBD ---                                                                                    ;;
536
;;------------------------------------------------------------------------------------------------;;
537
;< eax = 0 (ok) / -1 (fail)                                                                       ;;
538
;< [f.pos] = new cursor position (right after '=' char if eax = 0, at the end of file or right    ;;
539
;<           before '[' char otherwise)                                                           ;;
540
;;================================================================================================;;
541
	push	ebx edi
542
 
543
  .next_value:
544
	mov	edi, [_key_name]
545
	stdcall ini._.skip_line, [_f]
546
	stdcall ini._.skip_nonblanks, [_f]
547
	or	al, al
548
	jz	.exit_error
549
	cmp	al, '['
550
	je	.exit_error
551
    @@: stdcall ini._.get_char, [_f]
552
	or	al, al
553
	jz	.exit_error
554
	cmp	al, '='
555
	je	@f
556
	scasb
557
	je	@b
558
	cmp	byte[edi - 1], 0
559
	jne	.next_value
560
	dec	edi
561
	stdcall ini._.unget_char, [_f]
562
	stdcall ini._.skip_spaces, [_f]
563
	stdcall ini._.get_char, [_f]
564
	cmp	al, '='
565
	je	@f
566
	jmp	.next_value
567
    @@:
568
	cmp	byte[edi], 0
569
	jne	.next_value
570
 
571
	pop	edi ebx
572
	xor	eax, eax
573
	ret
574
 
575
  .exit_error:
576
	pop	edi ebx
577
	or	eax, -1
578
	ret
579
endp
580
 
581
;;================================================================================================;;
582
proc ini._.low.read_value _f_addr, _buffer, _buf_len ;////////////////////////////////////////////;;
583
;;------------------------------------------------------------------------------------------------;;
584
;? --- TBD ---                                                                                    ;;
585
;;------------------------------------------------------------------------------------------------;;
586
;> --- TBD ---                                                                                    ;;
587
;;------------------------------------------------------------------------------------------------;;
588
;< --- TBD ---                                                                                    ;;
589
;;================================================================================================;;
590
	push	edi eax
591
	mov	edi, [_buffer]
592
	stdcall ini._.skip_spaces, [_f_addr]
593
    @@: dec	[_buf_len]
594
	jz	@f
595
	stdcall ini._.get_char, [_f_addr]
596
	cmp	al, 13
597
	je	@f
598
	cmp	al, 10
599
	je	@f
600
	stosb
601
	or	al, al
602
	jnz	@b
603
    @@: stdcall ini._.unget_char, [_f_addr]
604
	mov	byte[edi], 0
605
	dec	edi
606
    @@: cmp	byte[edi], 32
607
	ja	@f
608
	mov	byte[edi], 0
609
	dec	edi
610
	cmp	edi, [_buffer]
611
	jae	@b
612
    @@: pop	eax edi
613
	ret
614
endp
615
 
616
;;================================================================================================;;
617
proc ini.enum_sections _f_name, _callback ;///////////////////////////////////////////////////////;;
618
;;------------------------------------------------------------------------------------------------;;
619
;? --- TBD ---                                                                                    ;;
620
;;------------------------------------------------------------------------------------------------;;
621
;> _callback = callback function address: func(f_name, sec_name)                                  ;;
622
;;------------------------------------------------------------------------------------------------;;
623
;< --- TBD ---                                                                                    ;;
624
;;================================================================================================;;
625
locals
626
  f	  IniFile
627
  f_addr  dd ?
628
  sec_buf dd ?
629
endl
630
 
631
	push	ebx esi edi
632
 
633
	cld
634
 
635
	invoke	mem.alloc, ini.MAX_NAME_LEN
636
	or	eax, eax
637
	jz	.exit_error.2
638
	mov	[sec_buf], eax
639
 
640
	xor	eax, eax
641
	mov	[f.fh], eax
642
	mov	[f.buf], eax
643
	invoke	file.open, [_f_name], O_READ
644
	cmp	eax, 32
645
	jb	.exit_error
646
	mov	[f.fh], eax
647
	invoke	mem.alloc, ini.MEM_SIZE
648
	or	eax, eax
649
	jz	.exit_error
650
	mov	[f.buf], eax
651
	lea	ebx, [f]
652
	mov	[f_addr], ebx
653
 
654
	invoke	file.seek, [f.fh], SEEK_SET, 0
655
	stdcall ini._.preload_block, [f_addr]
656
 
657
  .next_section:
658
	stdcall ini._.find_next_section, [f_addr]
659
	or	eax, eax
660
	jnz	.exit_error
661
 
662
	stdcall ini._.get_char, [f_addr]
663
	stdcall ini._.skip_spaces, [f_addr]
664
;       inc     esi
665
;       dec     [f.cnt]
666
	mov	edi, [sec_buf]
667
    @@: stdcall ini._.get_char, [f_addr]
668
	cmp	al, ']'
669
	je	@f
670
	or	al, al
671
	jz	.exit_ok
672
	cmp	al, 13
673
	je	.next_section
674
	cmp	al, 10
675
	je	.next_section
676
	stosb
677
	jmp	@b
678
    @@: xor	al, al
679
	stosb
680
	add	edi, -2
681
    @@: cmp	byte[edi], 32
682
	ja	@f
683
	mov	byte[edi], 0
684
	dec	edi
685
	jmp	@b
686
    @@:
687
	pushad
688
	mov	eax, [f_addr]
689
	stdcall [_callback], [_f_name], [sec_buf]
690
	or	eax, eax
691
	popad
692
	jnz	.next_section
693
 
694
  .exit_ok:
695
	invoke	file.close, [f.fh]
696
	invoke	mem.free, [f.buf]
697
	invoke	mem.free, [sec_buf]
698
	xor	eax, eax
699
	pop	edi esi ebx
700
	ret
701
 
702
  .exit_error:
703
	invoke	file.close, [f.fh]
704
	invoke	mem.free, [f.buf]
705
	invoke	mem.free, [sec_buf]
706
  .exit_error.2:
707
	or	eax, -1
708
	pop	edi esi ebx
709
	ret
710
endp
711
 
712
;;================================================================================================;;
713
proc ini.enum_keys _f_name, _sec_name, _callback ;////////////////////////////////////////////////;;
714
;;------------------------------------------------------------------------------------------------;;
715
;? --- TBD ---                                                                                    ;;
716
;;------------------------------------------------------------------------------------------------;;
717
;> _callback = callback function address: func(f_name, sec_name, key_name, key_value)             ;;
718
;;------------------------------------------------------------------------------------------------;;
719
;< --- TBD ---                                                                                    ;;
720
;;================================================================================================;;
721
locals
722
  f	  IniFile
723
  f_addr  dd ?
724
  key_buf dd ?
725
  val_buf dd ?
726
endl
727
 
728
	push	ebx esi edi
729
 
730
	cld
731
 
732
	invoke	mem.alloc, ini.MAX_NAME_LEN
733
	or	eax, eax
734
	jz	.exit_error.3
735
	mov	[key_buf], eax
736
	invoke	mem.alloc, ini.MAX_VALUE_LEN
737
	or	eax, eax
738
	jz	.exit_error.2
739
	mov	[val_buf], eax
740
 
741
	xor	eax, eax
742
	mov	[f.fh], eax
743
	mov	[f.buf], eax
744
	invoke	file.open, [_f_name], O_READ
745
	cmp	eax, 32
746
	jb	.exit_error
747
	mov	[f.fh], eax
748
	invoke	mem.alloc, ini.MEM_SIZE
749
	or	eax, eax
750
	jz	.exit_error
751
	mov	[f.buf], eax
752
	lea	ebx, [f]
753
	mov	[f_addr], ebx
754
	stdcall ini._.find_section, ebx, [_sec_name]
755
	or	eax, eax
756
	jnz	.exit_error
757
 
758
  .next_key:
759
	stdcall ini._.skip_line, [f_addr]
760
	stdcall ini._.skip_nonblanks, [f_addr]
761
	or	al, al
762
	jz	.exit_error
763
	cmp	al, '['
764
	je	.exit_error
765
	mov	edi, [key_buf]
766
    @@: stdcall ini._.get_char, [f_addr]
767
	or	al, al
768
	jz	.exit_error
769
	cmp	al, '='
770
	je	@f
771
	stosb
772
	jmp	@b
773
    @@:
774
	xor	al, al
775
	stosb
776
	add	edi, -2
777
    @@: cmp	byte[edi], 32
778
	ja	@f
779
	mov	byte[edi], 0
780
	dec	edi
781
	jmp	@b
782
    @@: stdcall ini._.low.read_value, [f_addr], [val_buf], ini.MAX_VALUE_LEN
783
	pushad
784
	stdcall [_callback], [_f_name], [_sec_name], [key_buf], [val_buf]
785
	or	eax, eax
786
	popad
787
	jnz	.next_key
788
 
789
    @@: invoke	file.close, [f.fh]
790
	invoke	mem.free, [f.buf]
791
	xor	eax, eax
792
	stosb
793
	pop	edi esi ebx
794
	ret
795
 
796
  .exit_error:
797
	invoke	file.close, [f.fh]
798
	invoke	mem.free, [f.buf]
799
	invoke	mem.free, [val_buf]
800
  .exit_error.2:
801
	invoke	mem.free, [key_buf]
802
  .exit_error.3:
803
	or	eax, -1
804
	pop	edi esi ebx
805
	ret
806
endp
807
 
808
;;================================================================================================;;
809
proc ini.get_str _f_name, _sec_name, _key_name, _buffer, _buf_len, _def_val ;/////////////////////;;
810
;;------------------------------------------------------------------------------------------------;;
811
;? --- TBD ---                                                                                    ;;
812
;;------------------------------------------------------------------------------------------------;;
813
;> --- TBD ---                                                                                    ;;
814
;;------------------------------------------------------------------------------------------------;;
815
;< --- TBD ---                                                                                    ;;
816
;;================================================================================================;;
817
locals
818
  f	 IniFile
819
  f_addr dd ?
820
endl
821
 
822
	push	ebx esi edi
823
 
824
	xor	eax, eax
825
	mov	[f.fh], eax
826
	mov	[f.buf], eax
827
	invoke	file.open, [_f_name], O_READ
828
	cmp	eax, 32
829
	jb	.exit_error
830
	mov	[f.fh], eax
831
	invoke	mem.alloc, ini.MEM_SIZE
832
	or	eax, eax
833
	jz	.exit_error
834
	mov	[f.buf], eax
835
	lea	ebx, [f]
836
	mov	[f_addr], ebx
837
	stdcall ini._.find_section, ebx, [_sec_name]
838
	or	eax, eax
839
	jnz	.exit_error
840
 
841
	stdcall ini._.find_key, ebx, [_key_name]
842
	or	eax, eax
843
	jnz	.exit_error
844
 
845
	stdcall ini._.low.read_value, [f_addr], [_buffer], [_buf_len]
846
;       mov     edi, [_buffer]
847
;   @@: dec     [_buf_len]
848
;       jz      @f
849
;       stdcall ini.aux.get_char, [f_addr]
850
;       or      al, al
851
;       jz      @f
852
;       cmp     al, 13
853
;       je      @f
854
;       cmp     al, 10
855
;       je      @f
856
;       stosb
857
;       jmp     @b
858
    @@: invoke	file.close, [f.fh]
859
	invoke	mem.free, [f.buf]
860
	xor	eax, eax
861
	stosb
862
	pop	edi esi ebx
863
	ret
864
 
865
  .exit_error:
866
	invoke	file.close, [f.fh]
867
	invoke	mem.free, [f.buf]
868
	mov	esi, [_def_val]
869
	mov	edi, [_buffer]
870
    @@: lodsb
871
	stosb
872
	or	al, al
873
	jnz	@b
874
	or	eax, -1
875
	pop	edi esi ebx
876
	ret
877
endp
878
 
879
;;================================================================================================;;
880
proc ini.set_str _f_name, _sec_name, _key_name, _buffer, _buf_len ;///////////////////////////////;;
881
;;------------------------------------------------------------------------------------------------;;
882
;? --- TBD ---                                                                                    ;;
883
;;------------------------------------------------------------------------------------------------;;
884
;> --- TBD ---                                                                                    ;;
885
;;------------------------------------------------------------------------------------------------;;
886
;< --- TBD ---                                                                                    ;;
887
;;================================================================================================;;
888
locals
889
  f	 IniFile
890
  f_addr dd ?
891
endl
892
 
893
	push	ebx esi edi
894
 
895
	xor	eax, eax
896
	mov	[f.fh], eax
897
	mov	[f.buf], eax
898
	invoke	file.open, [_f_name], O_READ + O_WRITE + O_CREATE
899
	cmp	eax, 32
900
	jb	.exit_error
901
	mov	[f.fh], eax
902
	invoke	mem.alloc, ini.MEM_SIZE
903
	or	eax, eax
904
	jz	.exit_error
905
	mov	[f.buf], eax
906
	lea	ebx, [f]
907
	mov	[f_addr], ebx
908
 
909
	stdcall ini._.find_section, ebx, [_sec_name]
910
	or	eax, eax
911
	jnz	.create_section
912
 
913
	stdcall ini._.find_key, ebx, [_key_name]
914
	or	eax, eax
915
	jnz	.create_key
916
 
917
  .modify_key:
918
 
919
	stdcall ini._.get_value_length, [f_addr]
920
	sub	eax, [_buf_len]
921
	stdcall ini._.shift_content, [f_addr], eax
922
 
923
  .modify_key.ex:
924
	invoke	file.tell, [f.fh]
925
	sub	eax, [f.cnt]
926
;       dec     eax
927
	invoke	file.seek, [f.fh], SEEK_SET, eax
928
	invoke	file.write, [f.fh], [_buffer], [_buf_len]
929
 
930
	pop	edi esi ebx
931
	xor	eax, eax
932
	ret
933
 
934
  .create_key:
935
	mov	edi, [f.buf]
936
	add	edi, ini.BLOCK_SIZE
937
	push	edi
938
 
939
  .create_key.ex:
940
;       mov     word[edi], 0x0A0D
941
;       add     edi,2
942
	mov	esi, [_key_name]
943
	call	ini._.string_copy
944
	mov	byte[edi], '='
945
	inc	edi
946
	mov	esi, [_buffer]
947
	mov	ecx, [_buf_len]
948
	rep	movsb
949
	mov	word[edi], 0x0A0D
950
	add	edi, 2
951
	mov	eax, edi
952
 
953
	pop	edi
954
	sub	eax, edi
955
	mov	[_buffer], edi
956
	mov	[_buf_len], eax
957
	neg	eax
958
	stdcall ini._.shift_content, [f_addr], eax
959
 
960
	jmp	.modify_key.ex
961
 
962
  .create_section:
963
	mov	edi, [f.buf]
964
	add	edi, ini.BLOCK_SIZE
965
	push	edi
966
 
967
	mov	esi, [_sec_name]
968
;       mov     dword[edi], 0x0A0D + ('[' shl 16)
969
;       add     edi, 3
970
	mov	byte[edi], '['
971
	inc	edi
972
	call	ini._.string_copy
973
;       mov     byte[edi], ']'
974
;       inc     edi
975
	mov	dword[edi], ']' + (0x0A0D shl 8)
976
	add	edi, 3
977
 
978
	jmp	.create_key.ex
979
 
980
  .exit_error:
981
	pop	edi esi ebx
982
	or	eax, -1
983
	ret
984
endp
985
 
986
;;================================================================================================;;
987
proc ini.get_int _f_name, _sec_name, _key_name, _def_val ;////////////////////////////////////////;;
988
;;------------------------------------------------------------------------------------------------;;
989
;? --- TBD ---                                                                                    ;;
990
;;------------------------------------------------------------------------------------------------;;
991
;> --- TBD ---                                                                                    ;;
992
;;------------------------------------------------------------------------------------------------;;
993
;< --- TBD ---                                                                                    ;;
994
;;================================================================================================;;
995
locals
996
  f	 IniFile
997
  f_addr dd ?
998
endl
999
 
1000
	push	ebx esi edi
1001
 
1002
	xor	eax, eax
1003
	mov	[f.fh], eax
1004
	mov	[f.buf], eax
1005
	invoke	file.open, [_f_name], O_READ
1006
	cmp	eax, 32
1007
	jb	.exit_error
1008
	mov	[f.fh], eax
1009
	invoke	mem.alloc, ini.MEM_SIZE
1010
	or	eax, eax
1011
	jz	.exit_error
1012
	mov	[f.buf], eax
1013
	lea	ebx, [f]
1014
	mov	[f_addr], ebx
1015
	stdcall ini._.find_section, ebx, [_sec_name]
1016
	or	eax, eax
1017
	jnz	.exit_error
1018
 
1019
	stdcall ini._.find_key, ebx, [_key_name]
1020
	or	eax, eax
1021
	jnz	.exit_error
1022
 
783 mikedld 1023
	stdcall ini._.skip_nonblanks, [f_addr]
717 mikedld 1024
	xor	eax, eax
1025
	xor	ebx, ebx
1026
	xor	edx, edx
1027
	stdcall ini._.get_char, [f_addr]
1028
	cmp	al, '-'
1029
	jne	.lp1
1030
	inc	bh
1031
    @@: stdcall ini._.get_char, [f_addr]
1032
  .lp1: cmp	al, '0'
1033
	jb	@f
1034
	cmp	al, '9'
1035
	ja	@f
1036
	inc	bl
1037
	add	eax, -'0'
1038
	imul	edx, 10
1039
	add	edx, eax
1040
	jmp	@b
1041
    @@:
1042
	or	bl, bl
1043
	jz	.exit_error
1044
	or	bh, bh
1045
	jz	@f
1046
	neg	edx
1047
    @@: invoke	file.close, [f.fh]
1048
	invoke	mem.free, [f.buf]
1049
	mov	eax, edx
1050
	pop	edi esi ebx
1051
	ret
1052
 
1053
  .exit_error:
1054
	invoke	file.close, [f.fh]
1055
	invoke	mem.free, [f.buf]
1056
	mov	eax, [_def_val]
1057
	pop	edi esi ebx
1058
	ret
1059
endp
1060
 
1061
;;================================================================================================;;
1062
proc ini.set_int _f_name, _sec_name, _key_name, _val ;////////////////////////////////////////////;;
1063
;;------------------------------------------------------------------------------------------------;;
1064
;? --- TBD ---                                                                                    ;;
1065
;;------------------------------------------------------------------------------------------------;;
1066
;> --- TBD ---                                                                                    ;;
1067
;;------------------------------------------------------------------------------------------------;;
1068
;< --- TBD ---                                                                                    ;;
1069
;;================================================================================================;;
1070
locals
1071
  buf rb 16
1072
endl
1073
 
1074
	push	ecx edx edi
1075
 
1076
	lea	edi, [buf]
1077
	add	edi, 15
1078
	mov	eax, [_val]
1079
	or	eax, eax
1080
	jns	@f
1081
	mov	byte[edi], '-'
1082
	neg	eax
1083
	inc	edi
1084
    @@: mov	ecx, 10
1085
    @@: xor	edx, edx
1086
	idiv	ecx
1087
	add	dl, '0'
1088
	mov	[edi], dl
1089
	dec	edi
1090
	or	eax, eax
1091
	jnz	@b
1092
	lea	eax, [buf]
1093
	add	eax, 15
1094
	sub	eax, edi
1095
	inc	edi
1096
 
1097
	stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], edi, eax
1098
 
1099
	pop	edi edx ecx
1100
	ret
1101
endp
1102
 
1103
 
1104
;;================================================================================================;;
1105
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1106
;;================================================================================================;;
1107
;! Imported functions section                                                                     ;;
1108
;;================================================================================================;;
1109
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1110
;;================================================================================================;;
1111
 
1112
 
1113
align 16
1114
@IMPORT:
1115
 
1116
library \
1117
	libfile , 'libio.obj'
1118
 
1119
import	libfile 		    , \
1120
	file.size   , 'file.size'   , \ ; f_name
1121
	file.open   , 'file.open'   , \ ; f_name  f_mode
1122
	file.read   , 'file.read'   , \ ; f_descr buffer   buf_len
1123
	file.write  , 'file.write'  , \ ; f_descr buffer   buf_len
1124
	file.seek   , 'file.seek'   , \ ; f_descr f_origin f_where
1125
	file.eof?   , 'file.eof?'   , \ ; f_descr
1126
	file.seteof , 'file.seteof' , \ ; f_descr
1127
	file.tell   , 'file.tell'   , \ ; f_descr
1128
	file.close  , 'file.close'	; f_descr
1129
 
1130
 
1131
;;================================================================================================;;
1132
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1133
;;================================================================================================;;
1134
;! Exported functions section                                                                     ;;
1135
;;================================================================================================;;
1136
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1137
;;================================================================================================;;
1138
 
1139
 
1140
align 16
1141
@EXPORT:
1142
 
1143
export						  \
1144
	lib_init	  , 'lib_init'		, \
1145
	0x00040005	  , 'version'		, \
1146
	ini.enum_sections , 'ini.enum_sections' , \
1147
	ini.enum_keys	  , 'ini.enum_keys'	, \
1148
	ini.get_str	  , 'ini.get_str'	, \
1149
	ini.get_int	  , 'ini.get_int'	, \
1150
	ini.set_str	  , 'ini.set_str'	, \
1151
	ini.set_int	  , 'ini.set_int'