Subversion Repositories Kolibri OS

Rev

Rev 4422 | 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 ;;
1001 diamond 8
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
9
;; of the License, or (at your option) any later version.                                         ;;
717 mikedld 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  ;;
1001 diamond 13
;; Lesser General Public License for more details.                                                ;;
717 mikedld 14
;;                                                                                                ;;
1001 diamond 15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
16
;; If not, see .                                                    ;;
717 mikedld 17
;;                                                                                                ;;
18
;;================================================================================================;;
19
;;                                                                                                ;;
1048 mikedld 20
;; 2009-03-08 (mike.dld)                                                                          ;;
21
;;   bug-fixes:                                                                                   ;;
22
;;     - moved buffer bound check in libini._.low.read_value up (reported by Insolor)             ;;
23
;;   new features:                                                                                ;;
24
;;     - comments support (char is ini.COMMENT_CHAR, defaults to ';')                             ;;
25
;;       inline comments are not supported                                                        ;;
988 mikedld 26
;; 2008-12-29 (mike.dld)                                                                          ;;
27
;;   bug-fixes:                                                                                   ;;
28
;;     - unnecessary 'stosb' in ini.get_str was causing problems                                  ;;
995 mikedld 29
;;   new features:                                                                                ;;
30
;;     - new functions: ini.get_color and ini.set_color                                           ;;
845 mikedld 31
;; 2008-08-06 (mike.dld)                                                                          ;;
32
;;   changes:                                                                                     ;;
33
;;     - split private procs into libini_p.asm, added comments                                    ;;
717 mikedld 34
;; 2008-02-07 (mike.dld)                                                                          ;;
35
;;   changes:                                                                                     ;;
36
;;     - renamed all *.aux.* to *._.* to match overall libraries design                           ;;
37
;; 2007-09-26 (mike.dld)                                                                          ;;
38
;;   bug-fixes:                                                                                   ;;
39
;;     - value was not correctly trimmed (reported by diamond)                                    ;;
40
;; 2007-08-01 (mike.dld)                                                                          ;;
41
;;   bug-fixes:                                                                                   ;;
42
;;     - serious defect in ini.set_str causing displaced write operations                         ;;
43
;;       (reported by diamond)                                                                    ;;
44
;;     - another serious defect in ini.enum_keys introduced with refactoring                      ;;
45
;;   changes:                                                                                     ;;
46
;;     - callback for enum_keys now takes additional parameter - key value                        ;;
47
;;     - handling trailing spaces in section/key/value                                            ;;
48
;; 2007-05-19 (mike.dld)                                                                          ;;
49
;;   bug-fixes:                                                                                   ;;
50
;;     - last char still wasn't read correctly                                                    ;;
51
;;     - digits of number were reversed when using ini.set_int                                    ;;
52
;;     - now using 'ini.aux.unget_char' instead of dangerous 'dec esi'                            ;;
53
;;   changes:                                                                                     ;;
54
;;     - all non-public functions now start with ini.aux.*                                        ;;
55
;;     - added ini.enum_sections and ini.enum_keys                                                ;;
56
;;     - removed ini.query_sec (use ini.enum_* instead)                                           ;;
57
;;                                                                                                ;;
58
;;================================================================================================;;
59
 
60
format MS COFF
61
 
62
public @EXPORT as 'EXPORTS'
63
 
64
include '../../../../proc32.inc'
65
include '../../../../macros.inc'
66
include '../libio/libio.inc'
1327 diamond 67
purge section,mov,add,sub
717 mikedld 68
 
69
include 'libini_p.inc'
70
 
845 mikedld 71
section '.flat' code readable align 16
717 mikedld 72
 
845 mikedld 73
include 'libini_p.asm'
717 mikedld 74
 
75
;;================================================================================================;;
76
proc ini.enum_sections _f_name, _callback ;///////////////////////////////////////////////////////;;
77
;;------------------------------------------------------------------------------------------------;;
4422 GerdtR 78
;? Enumerate sections, calling c2------------------------------------------------------------------;;
845 mikedld 79
;> _f_name = ini filename                                                                 ;;
80
;> _callback = callback function address: func(f_name, sec_name), where                           ;;
81
;>   f_name = ini filename (as passed to the function)                                    ;;
82
;>   sec_name = section name found                                                        ;;
717 mikedld 83
;;------------------------------------------------------------------------------------------------;;
845 mikedld 84
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 85
;;================================================================================================;;
86
locals
4422 GerdtR 87
  f	  IniFile
717 mikedld 88
  f_addr  dd ?
89
  sec_buf dd ?
90
endl
91
 
4422 GerdtR 92
	push	ebx esi edi
717 mikedld 93
 
4422 GerdtR 94
	cld
717 mikedld 95
 
4422 GerdtR 96
	invoke	mem.alloc, ini.MAX_NAME_LEN
97
	or	eax, eax
98
	jz	.exit_error.2
99
	mov	[sec_buf], eax
717 mikedld 100
 
4422 GerdtR 101
	xor	eax, eax
102
	mov	[f.fh], eax
103
	mov	[f.buf], eax
104
	invoke	file.open, [_f_name], O_READ
105
	cmp	eax, 32
106
	jb	.exit_file_error
107
	mov	[f.fh], eax
108
	invoke	mem.alloc, ini.MEM_SIZE
109
	or	eax, eax
110
	jz	.exit_error
111
	mov	[f.buf], eax
112
	lea	ebx, [f]
113
	mov	[f_addr], ebx
717 mikedld 114
 
4422 GerdtR 115
	invoke	file.seek, [f.fh], 0, SEEK_SET
116
	stdcall libini._.preload_block, [f_addr]
717 mikedld 117
 
118
  .next_section:
4422 GerdtR 119
	stdcall libini._.find_next_section, [f_addr]
120
	or	eax, eax
121
	jnz	.exit_error
717 mikedld 122
 
4422 GerdtR 123
	stdcall libini._.get_char, [f_addr]
124
	stdcall libini._.skip_spaces, [f_addr]
125
	mov	edi, [sec_buf]
845 mikedld 126
    @@: stdcall libini._.get_char, [f_addr]
4422 GerdtR 127
	cmp	al, ']'
128
	je	@f
129
	or	al, al
130
	jz	.exit_ok
131
	cmp	al, 13
132
	je	.next_section
133
	cmp	al, 10
134
	je	.next_section
135
	stosb
136
	jmp	@b
137
    @@: xor	al, al
138
	stosb
139
	add	edi, -2
140
    @@: cmp	byte[edi], 32
141
	ja	@f
142
	mov	byte[edi], 0
143
	dec	edi
144
	jmp	@b
717 mikedld 145
    @@:
4422 GerdtR 146
	pushad
147
	mov	eax, [f_addr]
148
	stdcall [_callback], [_f_name], [sec_buf]
149
	or	eax, eax
150
	popad
151
	jnz	.next_section
717 mikedld 152
 
153
  .exit_ok:
4422 GerdtR 154
	invoke	file.close, [f.fh]
155
	invoke	mem.free, [f.buf]
156
	invoke	mem.free, [sec_buf]
157
	xor	eax, eax
158
	pop	edi esi ebx
159
	ret
717 mikedld 160
 
161
  .exit_error:
4422 GerdtR 162
	invoke	file.close, [f.fh]
163
	invoke	mem.free, [f.buf]
3131 clevermous 164
  .exit_file_error:
4422 GerdtR 165
	invoke	mem.free, [sec_buf]
717 mikedld 166
  .exit_error.2:
4422 GerdtR 167
	or	eax, -1
168
	pop	edi esi ebx
169
	ret
717 mikedld 170
endp
171
 
172
;;================================================================================================;;
173
proc ini.enum_keys _f_name, _sec_name, _callback ;////////////////////////////////////////////////;;
174
;;------------------------------------------------------------------------------------------------;;
845 mikedld 175
;? Enumerate keys within a section, calling callback function for each of them                    ;;
717 mikedld 176
;;------------------------------------------------------------------------------------------------;;
845 mikedld 177
;> _f_name = ini filename                                                                 ;;
178
;> _sec_name = section name                                                               ;;
179
;> _callback = callback function address: func(f_name, sec_name, key_name, key_value), where      ;;
180
;>   f_name = ini filename (as passed to the function)                                    ;;
181
;>   sec_name = section name (as passed to the function)                                  ;;
182
;>   key_name = key name found                                                            ;;
183
;>   key_value = value of key found                                                       ;;
717 mikedld 184
;;------------------------------------------------------------------------------------------------;;
845 mikedld 185
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 186
;;================================================================================================;;
187
locals
4422 GerdtR 188
  f	  IniFile
717 mikedld 189
  f_addr  dd ?
190
  key_buf dd ?
191
  val_buf dd ?
192
endl
193
 
4422 GerdtR 194
	push	ebx esi edi
717 mikedld 195
 
4422 GerdtR 196
	cld
717 mikedld 197
 
4422 GerdtR 198
	invoke	mem.alloc, ini.MAX_NAME_LEN
199
	or	eax, eax
200
	jz	.exit_error.3
201
	mov	[key_buf], eax
202
	invoke	mem.alloc, ini.MAX_VALUE_LEN
203
	or	eax, eax
204
	jz	.exit_error.2
205
	mov	[val_buf], eax
717 mikedld 206
 
4422 GerdtR 207
	xor	eax, eax
208
	mov	[f.fh], eax
209
	mov	[f.buf], eax
210
	invoke	file.open, [_f_name], O_READ
211
	cmp	eax, 32
212
	jb	.exit_file_error
213
	mov	[f.fh], eax
214
	invoke	mem.alloc, ini.MEM_SIZE
215
	or	eax, eax
216
	jz	.exit_error
217
	mov	[f.buf], eax
218
	lea	ebx, [f]
219
	mov	[f_addr], ebx
220
	stdcall libini._.find_section, ebx, [_sec_name]
221
	or	eax, eax
222
	jnz	.exit_error
717 mikedld 223
 
224
  .next_key:
4422 GerdtR 225
	stdcall libini._.skip_line, [f_addr]
226
	stdcall libini._.skip_nonblanks, [f_addr]
227
	or	al, al
228
	jz	.exit_error
229
	cmp	al, '['
230
	je	.exit_error
231
	mov	edi, [key_buf]
845 mikedld 232
    @@: stdcall libini._.get_char, [f_addr]
4422 GerdtR 233
	or	al, al
234
	jz	.exit_error
235
	cmp	al, '='
236
	je	@f
237
	stosb
238
	jmp	@b
717 mikedld 239
    @@:
4422 GerdtR 240
	xor	al, al
241
	stosb
242
	add	edi, -2
243
    @@: cmp	byte[edi], 32
244
	ja	@f
245
	mov	byte[edi], 0
246
	dec	edi
247
	jmp	@b
845 mikedld 248
    @@: stdcall libini._.low.read_value, [f_addr], [val_buf], ini.MAX_VALUE_LEN
4422 GerdtR 249
	pushad
250
	stdcall [_callback], [_f_name], [_sec_name], [key_buf], [val_buf]
251
	or	eax, eax
252
	popad
253
	jnz	.next_key
717 mikedld 254
 
4422 GerdtR 255
    @@: invoke	file.close, [f.fh]
256
	invoke	mem.free, [f.buf]
257
	xor	eax, eax
258
	stosb
259
	pop	edi esi ebx
260
	ret
717 mikedld 261
 
262
  .exit_error:
4422 GerdtR 263
	invoke	file.close, [f.fh]
264
	invoke	mem.free, [f.buf]
3131 clevermous 265
  .exit_file_error:
4422 GerdtR 266
	invoke	mem.free, [val_buf]
717 mikedld 267
  .exit_error.2:
4422 GerdtR 268
	invoke	mem.free, [key_buf]
717 mikedld 269
  .exit_error.3:
4422 GerdtR 270
	or	eax, -1
271
	pop	edi esi ebx
272
	ret
717 mikedld 273
endp
274
 
275
;;================================================================================================;;
276
proc ini.get_str _f_name, _sec_name, _key_name, _buffer, _buf_len, _def_val ;/////////////////////;;
277
;;------------------------------------------------------------------------------------------------;;
845 mikedld 278
;? Read string                                                                                    ;;
717 mikedld 279
;;------------------------------------------------------------------------------------------------;;
845 mikedld 280
;> _f_name = ini filename                                                                 ;;
281
;> _sec_name = section name                                                               ;;
282
;> _key_name = key name                                                                   ;;
283
;> _buffer = destination buffer address                                                    ;;
284
;> _buf_len = buffer size (maximum bytes to read)                                          ;;
285
;> _def_val = default value to return if no key, section or file found                    ;;
717 mikedld 286
;;------------------------------------------------------------------------------------------------;;
845 mikedld 287
;< eax = -1 (error) / 0                                                                           ;;
288
;< [_buffer] = [_def_val] (error) / found key value                                       ;;
717 mikedld 289
;;================================================================================================;;
290
locals
4422 GerdtR 291
  f	 IniFile
717 mikedld 292
  f_addr dd ?
293
endl
294
 
4422 GerdtR 295
	push	ebx esi edi
717 mikedld 296
 
4422 GerdtR 297
	xor	eax, eax
298
	mov	[f.fh], eax
299
	mov	[f.buf], eax
300
	invoke	file.open, [_f_name], O_READ
301
	cmp	eax, 32
302
	jb	.exit_file_error
303
	mov	[f.fh], eax
304
	invoke	mem.alloc, ini.MEM_SIZE
305
	or	eax, eax
306
	jz	.exit_error
307
	mov	[f.buf], eax
308
	lea	ebx, [f]
309
	mov	[f_addr], ebx
310
	stdcall libini._.find_section, ebx, [_sec_name]
311
	or	eax, eax
312
	jnz	.exit_error
717 mikedld 313
 
4422 GerdtR 314
	stdcall libini._.find_key, ebx, [_key_name]
315
	or	eax, eax
316
	jnz	.exit_error
717 mikedld 317
 
4422 GerdtR 318
	stdcall libini._.low.read_value, [f_addr], [_buffer], [_buf_len]
319
    @@: invoke	file.close, [f.fh]
320
	invoke	mem.free, [f.buf]
321
	xor	eax, eax
322
	pop	edi esi ebx
323
	ret
717 mikedld 324
 
325
  .exit_error:
4422 GerdtR 326
	invoke	file.close, [f.fh]
327
	invoke	mem.free, [f.buf]
3131 clevermous 328
  .exit_file_error:
4422 GerdtR 329
	mov	edi, [_buffer]
330
	mov	esi, [_def_val]
331
	xor	al, al
332
	or	esi, esi
333
	jz	.exit_error.2
717 mikedld 334
    @@: lodsb
988 mikedld 335
  .exit_error.2:
4422 GerdtR 336
	stosb
337
	or	al, al
338
	jnz	@b
339
	or	eax, -1
340
	pop	edi esi ebx
341
	ret
717 mikedld 342
endp
343
 
344
;;================================================================================================;;
345
proc ini.set_str _f_name, _sec_name, _key_name, _buffer, _buf_len ;///////////////////////////////;;
346
;;------------------------------------------------------------------------------------------------;;
845 mikedld 347
;? Write string                                                                                   ;;
717 mikedld 348
;;------------------------------------------------------------------------------------------------;;
845 mikedld 349
;> _f_name = ini filename                                                                 ;;
350
;> _sec_name = section name                                                               ;;
351
;> _key_name = key name                                                                   ;;
352
;> _buffer = source buffer address                                                         ;;
353
;> _buf_len = buffer size (bytes to write)                                                 ;;
717 mikedld 354
;;------------------------------------------------------------------------------------------------;;
845 mikedld 355
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 356
;;================================================================================================;;
357
locals
4422 GerdtR 358
  f	 IniFile
717 mikedld 359
  f_addr dd ?
360
endl
361
 
4422 GerdtR 362
	push	ebx esi edi
717 mikedld 363
 
4422 GerdtR 364
	xor	eax, eax
365
	mov	[f.fh], eax
366
	mov	[f.buf], eax
367
	invoke	file.open, [_f_name], O_READ + O_WRITE + O_CREATE
368
	cmp	eax, 32
369
	jb	.exit_file_error
370
	mov	[f.fh], eax
371
	invoke	mem.alloc, ini.MEM_SIZE
372
	or	eax, eax
373
	jz	.exit_error
374
	mov	[f.buf], eax
375
	lea	ebx, [f]
376
	mov	[f_addr], ebx
717 mikedld 377
 
4422 GerdtR 378
						;/GerdtR - bugfix: at end of file required empty line
379
	invoke	file.seek, [f.fh],2,SEEK_END
380
	invoke	file.read, [f.fh],[f.buf],2
381
	mov	edx,[f.buf]
382
	cmp	word[edx],0A0Dh
383
	je	@f
384
	mov	word[edx],0A0Dh
385
	invoke	file.seek, [f.fh],0,SEEK_END
386
	invoke	file.write, [f.fh],[f.buf],2
387
    @@:
717 mikedld 388
 
4422 GerdtR 389
;        lea    ebx, [f]
390
						;\GerdtR
717 mikedld 391
 
4422 GerdtR 392
	stdcall libini._.find_section, ebx, [_sec_name]
393
	or	eax, eax
394
	jnz	.create_section
395
 
396
	stdcall libini._.find_key, ebx, [_key_name]
397
	or	eax, eax
398
	jnz	.create_key
399
 
717 mikedld 400
  .modify_key:
4422 GerdtR 401
	stdcall libini._.get_value_length, [f_addr]
402
	sub	eax, [_buf_len]
403
	stdcall libini._.shift_content, [f_addr], eax
717 mikedld 404
 
405
  .modify_key.ex:
4422 GerdtR 406
	invoke	file.tell, [f.fh]
407
	sub	eax, [f.cnt]
408
	invoke	file.seek, [f.fh], eax, SEEK_SET
409
	invoke	file.write, [f.fh], [_buffer], [_buf_len]
717 mikedld 410
 
4422 GerdtR 411
	invoke	file.close, [f.fh]
412
	pop	edi esi ebx
413
	mcall	68,13,[f.buf]
414
	xor	eax, eax
415
	ret
717 mikedld 416
 
417
  .create_key:
4422 GerdtR 418
	mov	edi, [f.buf]
419
	add	edi, ini.BLOCK_SIZE
420
	push	edi
717 mikedld 421
 
422
  .create_key.ex:
4422 GerdtR 423
	mov	esi, [_key_name]
424
	call	libini._.string_copy
425
	mov	byte[edi], '='
426
	inc	edi
427
	mov	esi, [_buffer]
428
	mov	ecx, [_buf_len]
429
	rep	movsb
430
	mov	word[edi], 0x0A0D
431
	add	edi, 2
432
	mov	eax, edi
717 mikedld 433
 
4422 GerdtR 434
	pop	edi
435
	sub	eax, edi
436
	mov	[_buffer], edi
437
	mov	[_buf_len], eax
438
	neg	eax
439
	stdcall libini._.shift_content, [f_addr], eax
717 mikedld 440
 
4422 GerdtR 441
	jmp	.modify_key.ex
717 mikedld 442
 
443
  .create_section:
4422 GerdtR 444
	mov	edi, [f.buf]
445
	add	edi, ini.BLOCK_SIZE
446
	push	edi
717 mikedld 447
 
4422 GerdtR 448
	mov	esi, [_sec_name]
717 mikedld 449
 
4422 GerdtR 450
	mov	byte[edi], '['
451
	inc	edi
452
	call	libini._.string_copy
453
	mov	dword[edi], ']' + (0x0A0D shl 8)
454
	add	edi, 3
717 mikedld 455
 
4422 GerdtR 456
	jmp	.create_key.ex
457
 
717 mikedld 458
  .exit_error:
4422 GerdtR 459
	invoke	file.close, [f.fh]
3131 clevermous 460
  .exit_file_error:
4422 GerdtR 461
	pop	edi esi ebx
462
	or	eax, -1
463
	ret
717 mikedld 464
endp
465
 
466
;;================================================================================================;;
467
proc ini.get_int _f_name, _sec_name, _key_name, _def_val ;////////////////////////////////////////;;
468
;;------------------------------------------------------------------------------------------------;;
845 mikedld 469
;? Read integer                                                                                   ;;
717 mikedld 470
;;------------------------------------------------------------------------------------------------;;
845 mikedld 471
;> _f_name = ini filename                                                                 ;;
472
;> _sec_name = section name                                                               ;;
473
;> _key_name = key name                                                                   ;;
474
;> _def_val = default value to return if no key, section or file found                     ;;
717 mikedld 475
;;------------------------------------------------------------------------------------------------;;
845 mikedld 476
;< eax = [_def_val] (error) / found key value                                              ;;
717 mikedld 477
;;================================================================================================;;
478
locals
4422 GerdtR 479
  f	 IniFile
717 mikedld 480
  f_addr dd ?
481
endl
482
 
4422 GerdtR 483
	push	edx ebx esi edi
717 mikedld 484
 
4422 GerdtR 485
	xor	eax, eax
486
	mov	[f.fh], eax
487
	mov	[f.buf], eax
488
	invoke	file.open, [_f_name], O_READ
489
	cmp	eax, 32
490
	jb	.exit_file_error
491
	mov	[f.fh], eax
492
	invoke	mem.alloc, ini.MEM_SIZE
493
	or	eax, eax
494
	jz	.exit_error
495
	mov	[f.buf], eax
496
	lea	ebx, [f]
497
	mov	[f_addr], ebx
498
	stdcall libini._.find_section, ebx, [_sec_name]
499
	or	eax, eax
500
	jnz	.exit_error
717 mikedld 501
 
4422 GerdtR 502
	stdcall libini._.find_key, ebx, [_key_name]
503
	or	eax, eax
504
	jnz	.exit_error
717 mikedld 505
 
4422 GerdtR 506
	stdcall libini._.skip_spaces, [f_addr]
507
	xor	eax, eax
508
	xor	ebx, ebx
509
	xor	edx, edx
510
	stdcall libini._.get_char, [f_addr]
511
	cmp	al, '-'
512
	jne	.lp1
513
	inc	bh
845 mikedld 514
    @@: stdcall libini._.get_char, [f_addr]
4422 GerdtR 515
  .lp1: cmp	al, '0'
516
	jb	@f
517
	cmp	al, '9'
518
	ja	@f
519
	inc	bl
520
	add	eax, -'0'
521
	imul	edx, 10
522
	add	edx, eax
523
	jmp	@b
717 mikedld 524
    @@:
4422 GerdtR 525
	or	bl, bl
526
	jz	.exit_error
527
	or	bh, bh
528
	jz	@f
529
	neg	edx
530
    @@: invoke	file.close, [f.fh]
531
	invoke	mem.free, [f.buf]
532
	mov	eax, edx
533
	pop	edi esi ebx edx
534
	ret
717 mikedld 535
 
536
  .exit_error:
4422 GerdtR 537
	invoke	file.close, [f.fh]
3131 clevermous 538
  .exit_file_error:
4422 GerdtR 539
	invoke	mem.free, [f.buf]
540
	mov	eax, [_def_val]
541
	pop	edi esi ebx edx
542
	ret
717 mikedld 543
endp
544
 
545
;;================================================================================================;;
546
proc ini.set_int _f_name, _sec_name, _key_name, _val ;////////////////////////////////////////////;;
547
;;------------------------------------------------------------------------------------------------;;
845 mikedld 548
;? Write integer                                                                                  ;;
717 mikedld 549
;;------------------------------------------------------------------------------------------------;;
845 mikedld 550
;> _f_name = ini filename                                                                 ;;
551
;> _sec_name = section name                                                               ;;
552
;> _key_name = key name                                                                   ;;
553
;> _val = value                                                                            ;;
717 mikedld 554
;;------------------------------------------------------------------------------------------------;;
845 mikedld 555
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 556
;;================================================================================================;;
557
locals
558
  buf rb 16
3832 GerdtR 559
  bNeg rd 1
717 mikedld 560
endl
561
 
4422 GerdtR 562
	push	ecx edx edi
717 mikedld 563
 
4422 GerdtR 564
	lea	edi, [buf]
565
	add	edi, 15
3832 GerdtR 566
 
4422 GerdtR 567
	mov	eax, [_val]
568
	mov	[bNeg],0
569
	or	eax, eax
570
	jns	@f
571
	mov	[bNeg],1
572
	neg	eax
3832 GerdtR 573
 
4422 GerdtR 574
    @@: mov	ecx, 10
575
    @@: xor	edx, edx
576
	idiv	ecx
577
	add	dl, '0'
578
	mov	[edi], dl
579
	dec	edi
580
	or	eax, eax
581
	jnz	@b
3832 GerdtR 582
 
4422 GerdtR 583
	cmp	[bNeg],0
584
	je	@f
585
	mov	byte[edi], '-'
586
	dec	edi
3832 GerdtR 587
     @@:
4422 GerdtR 588
	lea	eax, [buf]
589
	add	eax, 15
590
	sub	eax, edi
591
	inc	edi
717 mikedld 592
 
3832 GerdtR 593
 
594
 
4422 GerdtR 595
	stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], edi, eax
717 mikedld 596
 
4422 GerdtR 597
	pop	edi edx ecx
598
	ret
717 mikedld 599
endp
600
 
988 mikedld 601
;;================================================================================================;;
602
proc ini.get_color _f_name, _sec_name, _key_name, _def_val ;//////////////////////////////////////;;
603
;;------------------------------------------------------------------------------------------------;;
604
;? Read color                                                                                     ;;
605
;;------------------------------------------------------------------------------------------------;;
606
;> _f_name = ini filename                                                                 ;;
607
;> _sec_name = section name                                                               ;;
608
;> _key_name = key name                                                                   ;;
609
;> _def_val = default value to return if no key, section or file found                     ;;
610
;;------------------------------------------------------------------------------------------------;;
611
;< eax = [_def_val] (error) / found key value                                              ;;
612
;;================================================================================================;;
613
locals
614
  buf rb 14
615
endl
717 mikedld 616
 
4422 GerdtR 617
	push	ebx esi edi
988 mikedld 618
 
4422 GerdtR 619
	lea	esi, [buf]
620
	stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 14, 0
621
	cmp	byte[esi],0
622
	je	.exit_error
988 mikedld 623
 
4422 GerdtR 624
	xor	ebx, ebx
625
	stdcall libini._.str_to_int
626
	movzx	ebx, al
627
	shl	ebx, 16
628
	lodsb
629
	cmp	al, ','
630
	jne	@f
631
	stdcall libini._.str_to_int
632
	mov	bh, al
633
	lodsb
634
	cmp	al, ','
635
	jne	@f
636
	stdcall libini._.str_to_int
637
	mov	bl, al
988 mikedld 638
 
4422 GerdtR 639
    @@: mov	eax, ebx
988 mikedld 640
 
4422 GerdtR 641
	pop	edi esi ebx
642
	ret
988 mikedld 643
 
644
  .exit_error:
4422 GerdtR 645
	mov	eax, [_def_val]
646
	pop	edi esi ebx
647
	ret
988 mikedld 648
endp
649
 
717 mikedld 650
;;================================================================================================;;
988 mikedld 651
proc ini.set_color _f_name, _sec_name, _key_name, _val ;//////////////////////////////////////////;;
652
;;------------------------------------------------------------------------------------------------;;
653
;? Write color                                                                                    ;;
654
;;------------------------------------------------------------------------------------------------;;
655
;> _f_name = ini filename                                                                 ;;
656
;> _sec_name = section name                                                               ;;
657
;> _key_name = key name                                                                   ;;
658
;> _val = value                                                                            ;;
659
;;------------------------------------------------------------------------------------------------;;
660
;< eax = -1 (error) / 0                                                                           ;;
661
;;================================================================================================;;
662
locals
663
  buf rb 16
664
endl
665
 
4422 GerdtR 666
	push	ecx edx edi
988 mikedld 667
 
4422 GerdtR 668
	lea	edi, [buf]
669
	mov	ecx, 10
670
	mov	ebx, [_val]
671
	mov	eax, ebx
672
	shr	eax, 16
673
	and	eax, 0x0ff
674
	stdcall libini._.int_to_str
675
	mov	byte[edi], ','
676
	inc	edi
677
	movzx	eax, bh
678
	stdcall libini._.int_to_str
679
	mov	byte[edi], ','
680
	inc	edi
681
	movzx	eax, bl
682
	stdcall libini._.int_to_str
988 mikedld 683
 
4422 GerdtR 684
	lea	eax, [buf]
685
	sub	edi, eax
988 mikedld 686
 
4422 GerdtR 687
	stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], eax, edi
988 mikedld 688
 
4422 GerdtR 689
	pop	edi edx ecx
690
	ret
988 mikedld 691
endp
692
 
3832 GerdtR 693
 
1327 diamond 694
;;================================================================================================;;
3832 GerdtR 695
proc ini.del_section _f_name, _sec_name ;/////////////////////////////////////////////////////////;;
696
;;------------------------------------------------------------------------------------------------;;
697
;? Delete section and all key in this section                                                     ;;
698
;;------------------------------------------------------------------------------------------------;;
699
;> _f_name = ini filename                                                                 ;;
700
;> _sec_name = section name                                                               ;;
701
;;------------------------------------------------------------------------------------------------;;
702
;< eax = 0 - success                                                                              ;;
703
;<      -1 - file not found                                                                       ;;
704
;<       1 - section not found                                                                    ;;
705
;;================================================================================================;;
706
locals
4422 GerdtR 707
   funcFile	rb 25
708
   fileInfo	rb 40
709
   begMem	rd 1
710
   endMem	rd 1
711
   begDel	rd 1
712
   endDel	rd 1
3832 GerdtR 713
endl
4422 GerdtR 714
	push	ebx ecx edi esi
715
	xor	eax,eax
716
	mov	dword[funcFile],5		;get file info
717
	mov	dword[funcFile+4],eax
718
	mov	dword[funcFile+8],eax
719
	mov	dword[funcFile+12],eax
720
	lea	eax,[fileInfo]
721
	mov	dword[funcFile+16],eax
722
	mov	byte[funcFile+20],0
723
	m2m	dword[funcFile+21],[_f_name]
724
	lea	ebx,[funcFile]
725
	mcall	70
726
	test	eax,eax
727
	jz	@f
3832 GerdtR 728
 
4422 GerdtR 729
	or	eax,-1
730
	pop	esi edi ecx ebx
731
	ret
3832 GerdtR 732
      @@:
733
 
4422 GerdtR 734
	mov	ecx,dword[fileInfo+32]		;allocation mem for all file
735
	mcall	68,12
3832 GerdtR 736
 
4422 GerdtR 737
	mov	[begMem],eax
738
	mov	[endMem],eax
739
	add	[endMem],ecx
3832 GerdtR 740
 
4422 GerdtR 741
	mov	dword[funcFile],0		;read file to buffer
742
	mov	dword[funcFile+12],ecx
743
	mov	dword[funcFile+16],eax
744
	lea	ebx,[funcFile]
745
	mcall	70
3832 GerdtR 746
 
4422 GerdtR 747
	mov	edi,[begMem]			;search begin section
748
	jmp	.searchSect
3859 GerdtR 749
    .NoFindSect:
4422 GerdtR 750
	mov	edi,[begDel]
3832 GerdtR 751
    .searchSect:
4422 GerdtR 752
	mov	al,'['
753
	repne	scasb
754
	test	ecx,ecx
755
	jnz	@f
3859 GerdtR 756
 
4422 GerdtR 757
	pop	esi edi ecx ebx
758
	mov	eax,1
759
	ret
3832 GerdtR 760
      @@:
4422 GerdtR 761
	mov	[begDel],edi
762
	mov	esi,[_sec_name]
3832 GerdtR 763
      @@:
4422 GerdtR 764
	lodsb
765
	test	al,al
766
	jz	@f
767
	scasb
768
	jne	.NoFindSect
769
	jmp	@b
3832 GerdtR 770
      @@:
4422 GerdtR 771
	cmp	byte[edi],']'
772
	jne	.NoFindSect
3832 GerdtR 773
 
4422 GerdtR 774
	mov	edi,[begDel]
775
	dec	[begDel]
776
				       ;search end section
3832 GerdtR 777
    .searchEndSect:
4422 GerdtR 778
	mov	al,'['
779
	repne	scasb
7705 dunkaist 780
	jnz	@f
4422 GerdtR 781
	dec	edi
7705 dunkaist 782
      @@:
4422 GerdtR 783
	mov	[endDel],edi
3832 GerdtR 784
 
4422 GerdtR 785
	test	ecx,ecx
786
	jnz	@f
787
	jmp	.SaveToFile
3832 GerdtR 788
      @@:
789
 
790
 
4422 GerdtR 791
	mov	esi,[endDel]
792
	mov	edi,[begDel]
793
   @@:	lodsb
794
	stosb
795
	cmp	esi,[endMem]
796
	jb	@b
3832 GerdtR 797
 
798
   .SaveToFile:
4422 GerdtR 799
	mov	eax,dword[funcFile+12]
800
	sub	eax,[endDel]
801
	add	eax,[begDel]
3832 GerdtR 802
 
4422 GerdtR 803
	mov	dword[funcFile],2		;write buffer to file
804
	mov	dword[funcFile+12],eax
805
	m2m	dword[funcFile+16],[begMem]
806
	lea	ebx,[funcFile]
807
	mcall	70
3832 GerdtR 808
 
4422 GerdtR 809
	mcall	68,13,[begMem]
3920 mario79 810
 
4422 GerdtR 811
	xor	eax,eax
812
	pop	esi edi ecx ebx
813
	ret
3832 GerdtR 814
endp
815
 
816
 
817
;;================================================================================================;;
1327 diamond 818
proc ini.get_shortcut _f_name, _sec_name, _key_name, _def_val, _modifiers ;///////////////////////;;
819
;;------------------------------------------------------------------------------------------------;;
820
;? Read shortcut key                                                                              ;;
821
;;------------------------------------------------------------------------------------------------;;
822
;> _f_name = ini filename                                                                 ;;
823
;> _sec_name = section name                                                               ;;
824
;> _key_name = key name                                                                   ;;
825
;> _def_val = default value to return if no key, section or file found                     ;;
826
;> _modifiers = pointer to dword variable which receives modifiers state as in 66.4       ;;
827
;;------------------------------------------------------------------------------------------------;;
828
;< eax = [_def_val] (error) / shortcut key value as scancode                                 ;;
829
;< [[_modifiers]] = unchanged (error) / modifiers state for this shortcut                    ;;
830
;;================================================================================================;;
831
locals
832
  buf rb 64
833
endl
988 mikedld 834
 
4422 GerdtR 835
	push	ebx esi edi
1327 diamond 836
 
4422 GerdtR 837
	lea	esi, [buf]
838
	stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 64, 0
839
	cmp	byte[esi],0
840
	je	.exit_error
1327 diamond 841
 
4422 GerdtR 842
	xor	ebx, ebx	; ebx holds the value of modifiers
1327 diamond 843
.loop:
844
; test for end
4422 GerdtR 845
	xor	eax, eax
846
	cmp	byte [esi], al
847
	jz	.exit_ok	; exit with scancode zero
1327 diamond 848
; skip all '+'s
4422 GerdtR 849
	cmp	byte [esi], '+'
850
	jnz	@f
851
	inc	esi
852
	jmp	.loop
1327 diamond 853
@@:
854
; test for names
4422 GerdtR 855
	mov	edi, .names_table
856
	xor	edx, edx
1327 diamond 857
.names_loop:
4422 GerdtR 858
	movzx	ecx, byte [edi]
859
	inc	edi
860
	push	esi
1327 diamond 861
@@:
4422 GerdtR 862
	lodsb
863
	or	al, 20h
864
	scasb
865
	loopz	@b
866
	jz	.name_found
867
	pop	esi
868
	lea	edi, [edi+ecx+4]
869
	inc	edx
870
	cmp	byte [edi], 0
871
	jnz	.names_loop
1327 diamond 872
; special test: functional keys F
4422 GerdtR 873
	cmp	byte [esi], 'f'
874
	jz	@f
875
	cmp	byte [esi], 'F'
876
	jnz	.no_fx
1327 diamond 877
@@:
4422 GerdtR 878
	mov	edi, esi
879
	inc	esi
880
	call	libini._.str_to_int
881
	test	eax, eax
882
	jnz	.fx
883
	mov	esi, edi
1327 diamond 884
.no_fx:
885
; name not found, that must be usual key
4422 GerdtR 886
	movzx	eax, byte [esi]
887
	stdcall libini._.ascii_to_scan, eax
888
	test	eax, eax
889
	jz	.exit_error
1327 diamond 890
; all is ok
891
.exit_ok:
4422 GerdtR 892
	mov	ecx, [_modifiers]
893
	test	ecx, ecx
894
	jz	@f
895
	mov	[ecx], ebx
1327 diamond 896
 
897
@@:
898
 
4422 GerdtR 899
	pop	edi esi ebx
900
	ret
1327 diamond 901
 
902
.exit_error:
4422 GerdtR 903
	mov	eax, [_def_val]
904
	pop	edi esi ebx
905
	ret
1327 diamond 906
; handler for Fx
907
; eax = number
908
.fx:
4422 GerdtR 909
	cmp	eax, 10
910
	ja	@f
911
	add	eax, 3Bh-1
912
	jmp	.exit_ok
1327 diamond 913
@@:
4422 GerdtR 914
	add	eax, 57h-11
915
	jmp	.exit_ok
1327 diamond 916
; handlers for names
917
.name_found:
4422 GerdtR 918
	pop	eax	; ignore saved esi
919
	call	dword [edi]
920
	cmp	edx, .num_modifiers
921
	jae	.exit_ok
922
	jmp	.loop
1327 diamond 923
; modifiers
924
; syntax of value for each modifier:
925
; 0 = none, 1 = exactly one of L+R, 2 = both L+R, 3 = L, 4 = R
926
; Logic for switching: LShift+RShift=LShift+Shift=Shift+Shift, LShift+LShift=LShift
927
; generic modifier: 0->1->2->2, 3->2, 4->2
928
; left modifier: 0->3->3, 1->2->2, 4->2
929
; right modifier: 0->4->4, 1->2->2, 3->2
930
; Shift corresponds to first hex digit, Ctrl - second, Alt - third
931
macro shortcut_handle_modifiers name,reg,shift
932
{
933
local .set2,.set3,.set4
4422 GerdtR 934
.#name#_handler:	; generic modifier
935
	test	reg, 0xF
936
	jnz	.set2
1327 diamond 937
if shift
4422 GerdtR 938
	or	reg, 1 shl shift
1327 diamond 939
else
4422 GerdtR 940
	inc	reg
1327 diamond 941
end if
4422 GerdtR 942
	retn
1327 diamond 943
.set2:
4422 GerdtR 944
	and	reg, not (0xF shl shift)
945
	or	reg, 2 shl shift
946
	retn
1327 diamond 947
.l#name#_handler:
4422 GerdtR 948
	mov	al, reg
949
	and	al, 0xF shl shift
950
	jz	.set3
951
	cmp	al, 3 shl shift
952
	jnz	.set2
953
	retn
1327 diamond 954
.set3:
4422 GerdtR 955
	add	reg, 3 shl shift
956
	retn
1327 diamond 957
.r#name#_handler:
4422 GerdtR 958
	mov	al, reg
959
	and	al, 0xF shl shift
960
	jz	.set4
961
	cmp	al, 4 shl shift
962
	jnz	.set2
963
	retn
1327 diamond 964
.set4:
4422 GerdtR 965
	add	reg, 4 shl shift
966
	retn
1327 diamond 967
}
968
shortcut_handle_modifiers shift,bl,0
969
shortcut_handle_modifiers ctrl,bl,4
970
shortcut_handle_modifiers alt,bh,0
971
; names of keys
972
.name_handler:
4422 GerdtR 973
	movzx	eax, byte [.names_scancodes+edx-.num_modifiers]
974
	retn
1327 diamond 975
endp
976
 
977
; note: comparison ignores case, so this table keeps lowercase names
978
; macro does this
979
macro shortcut_name_with_handler name,handler
980
{
981
local .start, .end
4422 GerdtR 982
	db	.end - .start
1327 diamond 983
.start:
4422 GerdtR 984
	db	name
1327 diamond 985
.end:
986
repeat .end - .start
4422 GerdtR 987
	load .a byte from .start + % - 1
988
	store byte .a or 0x20 at .start + % - 1
1327 diamond 989
end repeat
4422 GerdtR 990
	dd	handler
1327 diamond 991
}
992
macro shortcut_name [name]
993
{
4422 GerdtR 994
	shortcut_name_with_handler name, .name_handler
1327 diamond 995
}
3832 GerdtR 996
 
1327 diamond 997
; all names here must be in english
998
; ... or modify lowercasing in macro and in comparison
999
.names_table:
1000
; generic modifiers
4422 GerdtR 1001
	shortcut_name_with_handler 'Ctrl', .ctrl_handler
1002
	shortcut_name_with_handler 'Alt', .alt_handler
1003
	shortcut_name_with_handler 'Shift', .shift_handler
1327 diamond 1004
; concrete modifiers
4422 GerdtR 1005
	shortcut_name_with_handler 'LCtrl', .lctrl_handler
1006
	shortcut_name_with_handler 'RCtrl', .rctrl_handler
1007
	shortcut_name_with_handler 'LAlt', .lalt_handler
1008
	shortcut_name_with_handler 'RAlt', .ralt_handler
1009
	shortcut_name_with_handler 'LShift', .lshift_handler
1010
	shortcut_name_with_handler 'RShift', .rshift_handler
1327 diamond 1011
.num_modifiers = 9
1012
; symbolic names of keys
4422 GerdtR 1013
	shortcut_name 'Home', 'End', 'PgUp', 'PgDn', 'Ins', 'Insert', 'Del', 'Delete'
1014
	shortcut_name 'Tab', 'Plus', 'Esc', 'Enter', 'Backspace', 'Space', 'Left', 'Right'
1015
	shortcut_name 'Up', 'Down'
1327 diamond 1016
; end of table
4422 GerdtR 1017
	db	0
1327 diamond 1018
ini.get_shortcut.names_scancodes:
1019
; scancodes for 'Home' ... 'Down'
4422 GerdtR 1020
	db	47h, 4Fh, 49h, 51h, 52h, 52h, 53h, 53h
1021
	db	0Fh, 4Eh, 01h, 1Ch, 0Eh, 39h, 4Bh, 4Dh
1022
	db	48h, 50h
1327 diamond 1023
 
988 mikedld 1024
;;================================================================================================;;
717 mikedld 1025
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1026
;;================================================================================================;;
1027
;! Imported functions section                                                                     ;;
1028
;;================================================================================================;;
1029
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1030
;;================================================================================================;;
1031
 
1032
 
1033
align 16
1034
@IMPORT:
1035
 
1036
library \
4422 GerdtR 1037
	libio , 'libio.obj'
717 mikedld 1038
 
4422 GerdtR 1039
import	libio			    , \
1040
	file.size   , 'file_size'   , \
1041
	file.open   , 'file_open'   , \
1042
	file.read   , 'file_read'   , \
1043
	file.write  , 'file_write'  , \
1044
	file.seek   , 'file_seek'   , \
1045
	file.eof?   , 'file_iseof'  , \
1046
	file.seteof , 'file_seteof' , \
1047
	file.tell   , 'file_tell'   , \
1048
	file.close  , 'file_close'
717 mikedld 1049
 
1050
 
1051
;;================================================================================================;;
1052
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1053
;;================================================================================================;;
1054
;! Exported functions section                                                                     ;;
1055
;;================================================================================================;;
1056
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1057
;;================================================================================================;;
1058
 
1059
 
1060
align 16
1061
@EXPORT:
1062
 
4422 GerdtR 1063
export						  \
1064
	libini._.init	  , 'lib_init'		, \
1065
	0x00080009	  , 'version'		, \
1066
	ini.enum_sections , 'ini_enum_sections' , \
1067
	ini.enum_keys	  , 'ini_enum_keys'	, \
1068
	ini.get_str	  , 'ini_get_str'	, \
1069
	ini.get_int	  , 'ini_get_int'	, \
1070
	ini.get_color	  , 'ini_get_color'	, \
1071
	ini.set_str	  , 'ini_set_str'	, \
1072
	ini.set_int	  , 'ini_set_int'	, \
1073
	ini.set_color	  , 'ini_set_color'	, \
1074
	ini.get_shortcut  , 'ini_get_shortcut'	, \
1075
	ini.del_section   , 'ini_del_section'