Subversion Repositories Kolibri OS

Rev

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